gpt4 book ai didi

c - 英特尔的时间戳读取 asm 代码示例是否使用了比必要的多两个寄存器?

转载 作者:太空狗 更新时间:2023-10-29 17:02:00 35 4
gpt4 key购买 nike

我正在研究使用 x86 CPU 中的时间戳寄存器 (TSR) 来衡量基准性能。这是一个有用的寄存器,因为它以不受时钟影响的单调时间单位进行测量速度变化。非常酷。

这是一份英特尔文档,显示了使用 TSR 进行可靠基准测试的 asm 片段,包括使用 cpuid 进行管道同步。见第 16 页:

http://www.intel.com/content/www/us/en/embedded/training/ia-32-ia-64-benchmark-code-execution-paper.html

要读取开始时间,它说(我注释了一点):

__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 并直接从 edx 中读取 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 的结果)。

谢谢

最佳答案

你是对的,这个例子很笨拙。 通常,如果 mov 是 inline-asm 语句中的第一条或最后一条指令,则说明您做错了,并且应该使用约束来告诉编译器您想要的位置输入,或输出的位置。

参见 my GNU C inline asm guides / links collection ,以及 中的其他链接标记维基。 ( 标签 wiki 也充满了一般 asm 的好东西。)


或者对于 rdtsc 具体来说,参见 Get CPU cycle count? 对于 __rdtsc() 内在的,以及@Mysticial 的回答中的良好内联 asm。


it measures in a monotonic unit of time which is immune to the clock speed changing.

是的,在过去 10 年左右制造的 CPU 上。

对于分析,以核心时钟周期为单位的时间通常更有用,而不是挂钟时间,so your microbenchmark results don't depend on power-saving / turbo.性能计数器可以做到这一点以及更多。

不过,如果您想要实时,rdtsc 是实现它的开销最低的方法。


回复:评论中的讨论:是的 cpuid 用于序列化,确保 rdtsc 和后续指令在 CPUID 之后才能开始执行。您可以在 RDTSC 之后放置另一个 CPUID,但这会增加测量开销,而且我认为准确度/精度的增益接近于零。

LFENCE 是一种更便宜的替代方案,可用于 RDTSC。 instruction ref manual entry记录了这样一个事实,即它不会让后面的指令开始执行,直到它和前面的指令退休(从内核的乱序部分的 ROB/RS)。参见 Are loads and stores the only instructions that gets reordered? ,有关使用它的具体示例,请参阅 clflush to invalidate cache line via C function .与 cpuid 等真正的序列化指令不同,它不会刷新存储缓冲区。

(在最近未启用 Spectre 缓解措施的 AMD CPU 上,lfence 甚至没有部分序列化,并且根据 Agner Fog's testing 以每时钟 4 的速度运行。Is LFENCE serializing on AMD processors?)

玛格丽特布鲁姆挖出 this useful link ,这也证实了 LFENCE 根据英特尔的 SDM 序列化 RDTSC,并且还有一些关于如何围绕 RDTSC 进行序列化的其他内容。

关于c - 英特尔的时间戳读取 asm 代码示例是否使用了比必要的多两个寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38994549/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com