Robi używając xor reg, reg daje przewagę nad mov reg, 0? [duplikować]
To pytanie ma już tutaj odpowiedź:
Jaki jest najlepszy sposób na ustawienie rejestru na zero w zespole x86: xor, mov lub and? 1 odpowiedźIstnieją dwa dobrze znane sposoby na ustawienie rejestru liczby całkowitej na zero na x86.
Zarówno
mov reg, 0
lub
xor reg, reg
Istnieje opinia, że drugi wariant jest lepszy, ponieważ wartość 0 nie jest przechowywana w kodzie i zapisuje kilka bajtów wyprodukowanego kodu maszynowego. Jest to zdecydowanie dobre - używa się mniej pamięci podręcznej instrukcji, co może czasami umożliwić szybsze wykonanie kodu. Wiele kompilatorów tworzy taki kod.
Istnieje jednak formalnie zależność między instrukcją między instrukcją xor a dowolną wcześniejszą instrukcją, która zmienia ten sam rejestr. Ponieważ istnieje pewna zależność, ta druga instrukcja musi czekać, aż poprzednia zakończy się, co może zmniejszyć obciążenie jednostek procesora i pogorszyć wydajność.
add reg, 17
;do something else with reg here
xor reg, reg
Jest oczywiste, że wynik xor będzie dokładnie taki sam, niezależnie od początkowej wartości rejestru. Ale czy procesor jest w stanie to rozpoznać?
Próbowałem następującego testu w 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;
}
Przy optymalizacji wyłączone obie pętle zajmują dokładnie ten sam czas. Czy to w uzasadniony sposób dowodzi, że procesor uznaje, że nie ma zależnościxor reg, reg
instrukcja dotycząca wcześniejszegomov eax, 0
instrukcja? Co może być lepszym testem, aby to sprawdzić?