Есть два хорошо известных способа установить целочисленный регистр в нулевое значение на x86.
Либо
mov reg, 0
or
xor reg, reg
Есть мнение, что второй вариант лучше, так как в коде не сохраняется значение 0, что экономит несколько байт создаваемого машинного кода. Это, безусловно, хорошо — используется меньше кэша инструкций, и иногда это позволяет ускорить выполнение кода. Многие компиляторы создают такой код.
Однако формально существует зависимость между инструкциями между инструкцией xor и любой более ранней инструкцией, которая изменяет тот же регистр. Поскольку существует зависимость, последняя инструкция должна дождаться завершения первой, и это может снизить нагрузку на процессорные блоки и снизить производительность.
add reg, 17
;do something else with reg here
xor reg, reg
Очевидно, что результат xor будет точно таким же, независимо от начального значения регистра. Но способен ли процессор это распознать?
Я попробовал следующий тест в VC++7:
const int Count = 10 * 1000 * 1000 * 1000;
int _tmain(int argc, _TCHAR* argv[])
{
int i;
DWORD start = GetTickCount();
for( i = 0; i < Count ; i++ ) {
__asm {
mov eax, 10
xor eax, eax
};
}
DWORD diff = GetTickCount() - start;
start = GetTickCount();
for( i = 0; i < Count ; i++ ) {
__asm {
mov eax, 10
mov eax, 0
};
}
diff = GetTickCount() - start;
return 0;
}
При выключенной оптимизации оба цикла занимают одинаковое время. Является ли это разумным доказательством того, что процессор распознает отсутствие зависимости инструкции xor reg, reg
от более ранней инструкции mov eax, 0
? Что может быть лучшим тестом, чтобы проверить это?
xor reg, reg
трюк - старые добрые времена :) - person Nick Dandoulakis   schedule 16.07.2009Count
переполнена, поэтому циклы будут выполняться гораздо меньше циклов, чем вы ожидали - person phuclv   schedule 06.12.2013xor reg,reg
не требует исполнительного блока (обрабатывается при декодировании?). Он ломает зависимости отreg
, и частичное обновление флагов останавливается. И имеет меньшую кодировку. Нет веских причин для подходаmov
в последних версиях x86-64, если только вам не нужно сохранять флаги [e]. - person Brett Hale   schedule 10.02.2014xor
, по сравнению сmov
. Я написал ответ на более свежий вопрос, прежде чем увидел этот: stackoverflow.com/questions/33666617/ . Я думаю, что это лучший и более полный ответ, чем любой из них. В идеале они должны быть помечены как дубликаты друг друга. - person Peter Cordes   schedule 19.01.2016