gpt4 book ai didi

c - 为什么我应该在 x86 和 x86_x64 上以不同方式使用 'rdtsc'?

转载 作者:太空狗 更新时间:2023-10-29 16:32:25 25 4
gpt4 key购买 nike

我知道 rdtsc 将处理器时间戳计数器的当前值加载到两个寄存器中:EDX 和 EAX。为了在 x86 上获得它,我需要这样做(假设使用 Linux):

    unsigned long lo, hi;
asm( "rdtsc" : "=a" (lo), "=d" (hi));
return lo;

对于 x86_x64:

        unsigned long lo, hi;
asm( "rdtsc" : "=a" (lo), "=d" (hi) );
return( lo | (hi << 32) );

这是为什么呢?谁能给我解释一下?

最佳答案

RDTSC 总是将其 64 位结果写入 EDX 和 EAX 中的高/低两半,即使在 64 位模式下 (see the manual),不幸的是没有将 64 位 TSC 打包到 RAX 中。这就是为什么在 asm 语句之后需要额外的工作。

要从中生成单个 64 位整数,您需要将 hi 移动到它所属的位置,作为 unsigned long 的一部分。 lo 已经在正确的位置,并且写入这些 32 位寄存器会将两个寄存器的高位清零,因此我们可以将(移位的)一半放在一起,而不必对低半部分进行 AND。

在 x86-64 Linux 中,unsigned long 是 64 位类型,因此内核实际上使用了 RDTSC 返回值的两半。

32 位版本更简单的唯一原因是内核通过丢弃高半部分将结果截断为 32 位。如果您确实想要 32 位模式下的 64 位 TSC,同样的 C 源代码也可以在那里工作(使用 uint64_tunsigned long long),尽管它不会t 编译为移位和或指令。编译器只知道它有一个 64 位整数,其一半在 EDX 和 EAX 中。

另见 How to get the CPU cycle count in x86_64 from C++? - 对于实际使用,不要忘记使这些 asm volatile。否则,编译器可以假定重复执行此操作会产生相同的输出,例如end-start = 优化后为 0。

关于c - 为什么我应该在 x86 和 x86_x64 上以不同方式使用 'rdtsc'?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17401914/

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