x86で整数レジスタをゼロ値に設定する2つのよく知られた方法があります。
また
mov reg, 0
また
xor reg, reg
値0がコードに格納されておらず、生成されたマシンコードの数バイトを節約するため、2番目のバリアントの方が優れているという意見があります。これは間違いなく良いことです-使用される命令キャッシュが少なく、これによりコードの実行が速くなる場合があります。多くのコンパイラがそのようなコードを生成します。
ただし、正式には、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
ますか?これをチェックするためのより良いテストは何でしょうか?