Es gibt zwei bekannte Möglichkeiten, ein Ganzzahlregister auf x86 auf null zu setzen.Macht die Verwendung von xor reg, reg einen Vorteil gegenüber mov reg, 0?
Entweder
mov reg, 0
oder
xor reg, reg
Es gibt eine Meinung, dass die zweite Variante besser ist, da der Wert 0 im Code nicht gespeichert ist und speichert mehrere Bytes von Maschinencode erzeugt. Dies ist definitiv gut - es wird weniger Befehlscache verwendet und dies kann manchmal eine schnellere Codeausführung ermöglichen. Viele Compiler produzieren solchen Code.
Es gibt jedoch formal eine Abhängigkeit zwischen Anweisungen zwischen der xor-Anweisung und einer früheren Anweisung, die dasselbe Register ändert. Da es eine Abhängigkeit gibt, muss die letztere Anweisung warten, bis die erstere abgeschlossen ist, und dies könnte die Prozessoreinheitslast und die Verletzungsleistung reduzieren.
add reg, 17
;do something else with reg here
xor reg, reg
Es ist offensichtlich, dass das Ergebnis von XOR unabhängig vom anfänglichen Registerwert genau gleich ist. Aber kann der Prozessor dies erkennen?
Ich habe versucht, den folgenden Test in 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;
}
Mit Optimierungen aus beiden Schleifen nehmen genau die gleiche Zeit. Beweist dies vernünftigerweise, dass der Prozessor erkennt, dass es keine Abhängigkeit von xor reg, reg
Anweisung auf der früheren mov eax, 0
Anweisung gibt? Was könnte ein besserer Test sein, um dies zu überprüfen?
Ich denke, deshalb verwenden wir Hochsprachen. Wenn Sie wirklich wissen wollen, ändern Sie einfach die Codegen-Stufe, um das eine oder andere zu tun. Benchmark. Wähle das Beste aus. – jrockway
ah, die alte 'xor reg, reg 'Trick - gute alte Zeiten :) –
Ich denke, die x86-Architektur definiert explizit XOR reg, reg als die Abhängigkeit von reg. Siehe das Intel Architekturhandbuch. Ich würde MOV reg erwarten, ... das Gleiche zu tun, einfach weil es ein MOV ist. Deine wirkliche Wahl ist also, welche man weniger Platz benötigt (ich würde raten, dass die Ausführungszeit gleich ist), wenn dir Statusbits egal sind (XOR schädigt sie alle). –