我正在研究使用 x86 CPU 中的时间戳寄存器 (TSR) 来测量基准性能。这是一个有用的寄存器,因为它以不受时钟速度变化影响的单调时间单位进行测量。很酷。
这是一份英特尔文档,展示了使用 TSR 进行可靠基准测试的 asm 片段,包括使用 cpuid 进行管道同步。见第 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
and的值eax
。edx
为什么不删除 mov 并直接从and中读取 TSR 值eax
?像这样:
__asm volatile(
"cpuid\n\t"
"rdtsc\n\t"
//
: "=d" (cycles_high), "=a" (cycles_low) // outputs
: // inputs
: "%rbx", "%rcx"); // clobber
通过这样做,您可以节省两个寄存器,从而降低 C 编译器需要溢出的可能性。
我对吗?还是那些 MOV 具有某种战略意义?
(我同意你确实需要临时寄存器来读取停止时间,因为在那种情况下指令的顺序是相反的:你有 rdtscp,...,cpuid。cpuid 指令破坏了 rdtscp 的结果)。
谢谢