我正在编写一个 C 代码来测量获取信号量所需的时钟周期数。我正在使用 rdtsc,在对信号量进行测量之前,我连续两次调用 rdtsc 来测量开销。我在一个 for 循环中重复了很多次,然后我使用平均值作为 rdtsc 开销。
首先使用平均值是否正确?
尽管如此,这里的大问题是有时我会得到开销的负值(不一定是平均的,但至少是 for 循环内的部分)。
这也影响了操作所需的 cpu 周期数的连续计算,sem_wait()
有时结果也是负数。如果我写的不清楚,这里有我正在处理的代码的一部分。
为什么我会得到这样的负值?
(编者注:请参阅Get CPU cycle count?获取获取完整 64 位时间戳的正确且可移植的方法。"=A"
当为 x86-64 编译时,asm 约束只会获取低 32 位或高 32 位,具体取决于寄存器分配是否发生选择 RAX 或 RDX 作为uint64_t
输出。它不会选择edx:eax
.)
(编辑的第二条注释:哎呀,这就是为什么我们得到负面结果的答案。仍然值得在这里留下一个注释作为警告不要复制这个rdtsc
实现。)
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
static inline uint64_t get_cycles()
{
uint64_t t;
// editor's note: "=A" is unsafe for this in x86-64
__asm volatile ("rdtsc" : "=A"(t));
return t;
}
int num_measures = 10;
int main ()
{
int i, value, res1, res2;
uint64_t c1, c2;
int tsccost, tot, a;
tot=0;
for(i=0; i<num_measures; i++)
{
c1 = get_cycles();
c2 = get_cycles();
tsccost=(int)(c2-c1);
if(tsccost<0)
{
printf("#### ERROR!!! ");
printf("rdtsc took %d clock cycles\n", tsccost);
return 1;
}
tot = tot+tsccost;
}
tsccost=tot/num_measures;
printf("rdtsc takes on average: %d clock cycles\n", tsccost);
return EXIT_SUCCESS;
}