Я обнаружил, что!= и == не самые быстрые способы тестирования для нуля или ненулевого.
bool nonZero1 = integer != 0;
xor eax, eax
test ecx, ecx
setne al
bool nonZero2 = integer < 0 || integer > 0;
test ecx, ecx
setne al
bool zero1 = integer == 0;
xor eax, eax
test ecx, ecx
sete al
bool zero2 = !(integer < 0 || integer > 0);
test ecx, ecx
sete al
Компилятор: VС++ 11 Флаги оптимизации:/O2/GL/LTCG
Это сборка для x86-32. Вторая версия обоих сравнений была примерно на 12% быстрее как на x86-32, так и на x86-64. Тем не менее, на x86-64 инструкции были идентичны (первые версии выглядели точно так же, как и во второй версии), но вторые версии были еще быстрее.
- Почему компилятор не генерирует более быструю версию на x86-32?
- Почему вторая версия еще быстрее на x86-64, когда вывод сборки идентичен?
EDIT: я добавил код бенчмаркинга. ZERO: 1544 мс, 1358 мс NON_ZERO: 1544 мс, 1358 мс http://pastebin.com/m7ZSUrcP или http://anonymouse.org/cgi-bin/anon-www.cgi/http://pastebin.com/m7ZSUrcP
Примечание. Вероятно, неудобно находить эти функции при компиляции в одном исходном файле, потому что main.asm идет довольно большой. У меня был zero1, zero2, nonZero1, nonZero2 в отдельном исходном файле.
EDIT2: может ли кто-то с установленными VС++ 11 и VС++ 2010 запустить код сравнения и опубликовать тайминги? Это может быть ошибка в VС++ 11.