Il existe deux façons bien connues de définir un registre d'entier à valeur nulle sur x86.Est-ce que l'utilisation de xor reg, reg donne un avantage sur mov reg, 0?
Soit
mov reg, 0
ou
xor reg, reg
Il y a un avis que la deuxième variante est meilleure puisque la valeur 0 ne sont pas stockées dans le code et qui enregistre plusieurs octets de code machine produit. C'est certainement bon - moins de cache d'instructions est utilisé et cela peut parfois permettre une exécution plus rapide du code. De nombreux compilateurs produisent un tel code.
Cependant, il y a formellement une dépendance inter-instruction entre l'instruction xor et n'importe quelle instruction précédente qui change le même registre. Comme il y a une dérive, la dernière instruction doit attendre que la dernière instruction soit terminée, ce qui pourrait réduire la charge des unités de traitement et nuire aux performances.
add reg, 17
;do something else with reg here
xor reg, reg
Il est évident que le résultat de xor sera exactement le même quelle que soit la valeur du registre initial. Mais le processeur est-il capable de le reconnaître?
J'ai essayé le test suivant dans 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;
}
Avec des optimisations off les deux boucles prennent exactement en même temps. Cela prouve-t-il raisonnablement que le processeur reconnaît qu'il n'y a pas de dépendance de l'instruction xor reg, reg
sur l'instruction mov eax, 0
précédente? Quel pourrait être un meilleur test pour vérifier cela?
Je pense que c'est la raison pour laquelle nous utilisons des langages de haut niveau. Si vous voulez vraiment savoir, changez simplement l'étape du codegen pour faire l'un ou l'autre. Référence. Choisissez le meilleur. – jrockway
ah, le vieux 'xor reg, reg' truc - bon vieux temps :) –
Je pense que l'architecture x86 définit explicitement XOR reg, reg en tant que rupture de la dépendance sur reg. Voir le manuel d'architecture Intel. Je m'attendrais à ce que MOV reg ... fasse la même chose simplement parce que c'est un MOV. Donc, votre vrai choix est, lequel prend moins de place (je suppose que le temps d'exécution est le même), si vous ne vous souciez pas des bits d'état (XOR les endommage tous). –