我正在尝试用 rdtsc 替换 clock_gettime(CLOCK_REALTIME, &ts) 以根据 cpu 周期而不是服务器时间来基准代码执行时间。基准测试代码的执行时间对软件至关重要。我曾尝试在 x86_64 3.20GHz ubuntu 机器上的独立内核上运行代码,并得到以下数字:
案例 1:时钟获取时间: 24 纳秒
void gettime(Timespec &ts) {
clock_gettime(CLOCK_REALTIME, &ts);
}
案例 2:rdtsc(没有 mfence 和编译器屏障): 10 ns
void rdtsc(uint64_t& tsc) {
unsigned int lo,hi;
__asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
tsc = ((uint64_t)hi << 32) | lo;
}
案例 3:rdtsc(带有 mfence 和编译器屏障): 30 ns
void rdtsc(uint64_t& tsc) {
unsigned int lo,hi;
__asm__ __volatile__ ("mfence;rdtsc" : "=a" (lo), "=d" (hi) :: "memory");
tsc = ((uint64_t)hi << 32) | lo;
}
这里的问题是我知道 rdtsc 是一个非序列化调用,并且可以由 CPU 重新排序,另一种选择是 rdtscp,它是一个序列化调用,但 rdtscp 调用之后的指令可以在 rdtscp 调用之前重新排序。使用内存屏障会增加执行时间。
- 对延迟敏感代码进行基准测试的最优化和最佳方法是什么?
- 有没有优化我提到的案例?