函数__asm__ __volatile __("rdtsc");

use*_*629 -3 c++ x86 rdtsc

我不知道这段代码究竟是什么:

int rdtsc(){
    __asm__ __volatile__("rdtsc");
Run Code Online (Sandbox Code Playgroud)

拜托,有人可以解释一下吗?为什么"rdtsc"?

Mat*_*son 7

实际上,这根本不是很好的代码.

RDTSC 是x86指令"ReaD TimeStamp Counter" - 它读取一个64位计数器,它在处理器的每个时钟周期都会计数.

但由于它是一个64位的数字,它存储在EAX(低部分)和EDX(高部分),如果这个代码曾被用于内联的情况,编译器不知道它EDX正在被破坏.或者内联汇编在脱离非void函数结束之前设置EAX .

编译器不"理解"汇编代码,它是一个黑盒子,你必须用输入/输出操作数描述它,所以它知道有一个输出EDX:EAX.(或者,在输出EAXEDX被打一顿).我会这样做:

uint64_t rdtsc()
{
   uint32_t hi, lo;
   __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
   return ( (uint64_t)lo)|( ((uint64_t)hi)<<32 );
}
Run Code Online (Sandbox Code Playgroud)

因此,给出一个在现代机器上不会每秒或每两秒回绕一次的时间计数,它告诉编译器您的asm语句修改哪个寄存器.

或者使用__rdtsc()内部函数让编译器自己发出rdtsc指令,并知道输出的位置.请参阅获取CPU周期数?.


Max*_*kin 5

经常被引用的内联汇编程序使用gcc-7和更早的版本rdtsc生成出色的代码

一个更有效的解决方案是使用__builtin_ia32_rdtsc内置函数:

uint64_t tsc = __builtin_ia32_rdtsc();
Run Code Online (Sandbox Code Playgroud)