2010-10-09 63 views
10

取自this SO thread,這段代碼計算行//1//2之間的運行代碼所耗用的CPU週期數。這段代碼如何計算經過的CPU週期數?

$ cat cyc.c 
#include<stdio.h> 

static __inline__ unsigned long long rdtsc(void) 
{ 
    unsigned long long int x; 
    __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)); 
    return x; 
} 

int main() { 
    unsigned long long cycles = rdtsc(); //1 
    cycles = rdtsc() - cycles;   //2 
    printf("Time is %d\n", (unsigned)cycles); 
    return 0; 
} 

$ gcc cyc.c -o cyc 
$ ./cyc 
Time is 73 
$ ./cyc 
Time is 74 
$ ./cyc 
Time is 63 
$ ./cyc 
Time is 73 
$ 

如何進行rdtsc()功能工作?

回答

11

該函數執行x86指令RTDSC,它恰好有一個操作碼0x0f, 0x31。處理器在內部跟蹤時鐘週期,並讀取該數字。

當然,這隻適用於x86 proc,其他處理器將需要不同的指示。

時間戳記計數器是自Pentium以來所有x86處理器上存在的64位寄存器。它會計算自復位以來的滴答數量。指令RDTSC返回EDX中的TSC:EAX。它的操作碼是0F 31. [1]像Cyrix 6x86這樣的奔騰競爭者並不總是有TSC,並且可能認爲RDTSC是非法指令。 Cyrix在他們的信息產業部中包含一個時間戳計數器。

http://en.wikipedia.org/wiki/Time_Stamp_Counter

+0

什麼是' 「= A」'的一部分嗎? – Lazer 2010-10-10 06:25:45

+2

它在一些molticore AMD處理器上也有問題,因爲它們每個都有自己的計數器不同步,所以如果你碰巧在不同的內核上運行時間戳,你可能會有驚喜。因此,要求操作系統的這個線程運行在同一個核心上是一個好主意。 – ruslik 2010-10-10 10:54:27

+0

@Lazer,這是一個有點GCC魔術,說EDX中的值:EAX應該放入C變量x - http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints 。查看英特爾部分下的「A」條目。 – dsolimano 2010-10-10 18:58:55