x86 CPU にあるタイムスタンプ レジスタ (TSR) を使用してベンチマーク パフォーマンスを測定することを検討しています。クロック速度の変化の影響を受けない単調な時間単位で測定するため、これは便利なレジスタです。とてもかっこいい。
これは、パイプライン同期に cpuid を使用するなど、TSR を使用して確実にベンチマークを行うための asm スニペットを示す Intel ドキュメントです。16ページ参照:
開始時刻を読み取るには、次のように表示されます (少し注釈を付けました)。
__asm volatile (
"cpuid\n\t" // writes e[abcd]x
"rdtsc\n\t" // writes edx, eax
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t"
//
:"=r" (cycles_high), "=r" (cycles_low) // outputs
: // inputs
:"%rax", "%rbx", "%rcx", "%rdx"); // clobber
と の値を取得するためにスクラッチ レジスタが使用される理由が気にedx
なりeax
ます。movs を削除して、 と から TSR 値を読み取ってみませんedx
かeax
? このような:
__asm volatile(
"cpuid\n\t"
"rdtsc\n\t"
//
: "=d" (cycles_high), "=a" (cycles_low) // outputs
: // inputs
: "%rbx", "%rcx"); // clobber
これにより、2 つのレジスタが節約され、C コンパイラがスピルする必要が生じる可能性が低くなります。
私は正しいですか?それとも、それらの MOV は戦略的なものですか?
(そのシナリオでは命令の順序が逆になるため、停止時間を読み取るためにスクラッチ レジスタが必要であることに同意します。rdtscp、...、cpuid があります。cpuid 命令は rdtscp の結果を破棄します)。
ありがとう