2010-10-09 38 views
10

Lấy từ this SO thread, đoạn mã này tính toán số chu kỳ CPU đã trôi qua chạy mã giữa các dòng //1//2.Mã này tính toán số chu kỳ CPU đã trôi qua như thế nào?

$ 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 
$ 

Chức năng rdtsc() hoạt động như thế nào?

Trả lời

11

Hàm thực hiện lệnh RTDSC x86, có mã opcode là 0x0f, 0x31. Bộ xử lý theo dõi các chu kỳ đồng hồ trong nội bộ, và điều này đọc số đó.

Tất nhiên, điều này chỉ hoạt động trên x86 procs, các bộ vi xử lý khác sẽ cần hướng dẫn khác nhau.

Thanh ghi thời gian là đăng ký 64 bit có trên tất cả các bộ xử lý x86 kể từ Pentium. Nó đếm số lượng ve kể từ khi thiết lập lại. Hướng dẫn RDTSC trả về TSC trong EDX: EAX. Opcode của nó là 0F 31. [1] Các đối thủ cạnh tranh Pentium như Cyrix 6x86 không phải lúc nào cũng có TSC và có thể coi RDTSC là một hướng dẫn bất hợp pháp. Cyrix bao gồm một bộ đếm tem thời gian trong MII của họ.

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

+0

nào ' "= A"' phần làm gì? – Lazer

+2

Nó cũng có vấn đề đối với một số bộ xử lý AMD cực đoan, bởi vì mỗi bộ đếm của nó không được đồng bộ, vì vậy nếu bạn tình cờ chạy trên các lõi khác nhau khi bạn lấy dấu thời gian, bạn có thể có bất ngờ. Vì vậy, yêu cầu hệ điều hành cho thread này chạy trên cùng một lõi sẽ là một ý tưởng tốt. – ruslik

+0

@Lazer, đó là một chút phép thuật GCC mà nói rằng các giá trị trong EDX: EAX nên được đặt vào biến C x - http://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html#Machine-Constraints . Nhìn vào mục "A" trong phần Intel. – dsolimano

Các vấn đề liên quan