时间戳计时器
之前在做CSAPP:Lab_Performance的时候,查看代码遇到这个问题。查阅资料之后,整理、记录一下。
时间戳计时器 Time Stamp Counter(TSC)是自Pentium之后所有的x86处理器都有的一个64位寄存器。它对自上次重设之后的cycles的数量计数。指令RDSTC
将TSC返回到串联寄存器组EDX:EAX
中(即低32位保存在EAX
中,高32位保存在EDX
中)。在x86-64机器中,RDSTC
还会将RAX
和RDX
高32位清空。它的操作码是0F 31
。(以上定义,引用自(WIKIPEDIA)[https://en.wikipedia.org/wiki/Time_Stamp_Counter])
最近在查看CSAPP 对应的performance-lab的实现的时候,看到了clock.c中对于CPE计数的实现。它使用了汇编代码使用rdstc指令,来获取时间戳计时器的内容,然后对前后两次求差得到程序运行的CPE,另外由于该程序编写的年代比较久远,当时可能gcc对于64位数值还不支持,因此它使用了两个32位无符号整数ncyc_lo, ncyc_hi来分别存储rdstc指令返回的低32位和高32位,然后将结果保存在double类型result变量中。
另外,我在stack overflow中查看到还有另外一个版本使用的是rdstcp指令,在这里记录一下(stack overflow)[https://stackoverflow.com/questions/36666993/measuring-program-execution-time-with-cycle-counters],rdstcp其他特性和rdstc指令是一致的,除了会将ECX
寄存器设置为0以外,所以那个版本的实现可能会导致一些意想不到的错误。
/* perf-lab clock.c*/
#if IS_x86
/* $begin x86cyclecounter */
/* Initialize the cycle counter */
static unsigned cyc_hi = 0;
static unsigned cyc_lo = 0;
/* Set *hi and *lo to the high and low order bits of the cycle counter.
Implementation requires assembly code to use the rdtsc instruction. */
void access_counter(unsigned *hi, unsigned</