2012-03-27 38 views
10

Với Visual Studio Tôi có thể đọc số chu kỳ đồng hồ từ bộ xử lý như hình dưới đây. Làm thế nào để tôi làm điều tương tự với GCC?đếm chu kỳ đồng hồ wth GCC

#ifdef _MSC_VER    // Compiler: Microsoft Visual Studio 

    #ifdef _M_IX86      // Processor: x86 

     inline uint64_t clockCycleCount() 
     { 
      uint64_t c; 
      __asm { 
       cpuid  // serialize processor 
       rdtsc  // read time stamp counter 
       mov dword ptr [c + 0], eax 
       mov dword ptr [c + 4], edx 
      } 
      return c; 
     } 

    #elif defined(_M_X64)    // Processor: x64 

     extern "C" unsigned __int64 __rdtsc(); 
     #pragma intrinsic(__rdtsc) 
     inline uint64_t clockCycleCount() 
     { 
      return __rdtsc(); 
     } 

    #endif 

#endif 

Trả lời

15

Trên các phiên bản gần đây của Linux gettimeofday sẽ kết hợp thời gian nano giây.

Nếu bạn thực sự muốn gọi RDTSC bạn có thể sử dụng lắp ráp nội tuyến sau:

http://www.mcs.anl.gov/~kazutomo/rdtsc.html

#if defined(__i386__) 

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

#elif defined(__x86_64__) 

static __inline__ unsigned long long rdtsc(void) 
{ 
    unsigned hi, lo; 
    __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi)); 
    return ((unsigned long long)lo)|(((unsigned long long)hi)<<32); 
} 

#endif 
+1

Có, tôi thực sự cần RDTSC, và bây giờ tôi có nó. Cảm ơn bạn. – user763305

+0

mã này thiếu hướng dẫn tuần tự hóa, do đó, trên bất kỳ bộ xử lý hiện đại nào (không theo thứ tự), nó sẽ mang lại kết quả không chính xác. thường cpuid được sử dụng. – markhahn

+0

Phiên bản 64 bit tạo ra lắp ráp kém với gcc. Để cải thiện nó, hãy thay đổi các bit 32 bit ở bên trái và bằng 'rax' theo cách thủ công. Kết quả là trong 'rax'. –

5

Trên Linux với gcc, tôi sử dụng như sau:

/* define this somewhere */ 
#ifdef __i386 
__inline__ uint64_t rdtsc() { 
    uint64_t x; 
    __asm__ volatile ("rdtsc" : "=A" (x)); 
    return x; 
} 
#elif __amd64 
__inline__ uint64_t rdtsc() { 
    uint64_t a, d; 
    __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d)); 
    return (d<<32) | a; 
} 
#endif 

/* now, in your function, do the following */ 
uint64_t t; 
t = rdtsc(); 
// ... the stuff that you want to time ... 
t = rdtsc() - t; 
// t now contains the number of cycles elapsed 
19

Các khác câu trả lời có hiệu quả, nhưng bạn có thể tránh việc lắp ráp nội tuyến bằng cách sử dụng số nội tại __rdtsc của GCC, có sẵn bằng cách bao gồm x86intrin.h.

+0

Cần lưu ý rằng hiệu ứng sẽ khá giống nhau (nhưng dễ đọc hơn nhiều), vì nội tại này thường có chữ ký 'extern __inline unsigned long long __attribute __ ((__ gnu_inline__, __always_inline__, __artificial__)) __rdtsc (void) ', tức là nó vẫn sẽ được inlined trong kết quả nhị phân. – Joost