2012-03-27 14 views
10

Con Visual Studio posso leggere il conteggio del ciclo di clock dal processore come mostrato di seguito. Come faccio a fare la stessa cosa con GCC?conteggio del ciclo di clock con 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 

risposta

15

Nelle versioni recenti di gettimeofday di Linux sono incorporati i tempi di nanosecondo.

Se davvero si vuole chiamare RDTSC è possibile utilizzare il seguente assembly inline:

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

Sì, ho davvero bisogno di RDTSC, e ora ce l'ho. Grazie. – user763305

+0

questo codice manca di istruzioni di serializzazione, quindi su qualsiasi processore moderno (che è fuori servizio), produrrà risultati errati. di solito si usa CPUID. – markhahn

+0

La versione a 64 bit genera un assemblaggio scadente con gcc. Per migliorarlo, sposta 'rdx' 32 bit a sinistra o con' rax' manualmente. Il risultato è in 'rax'. –

5

su Linux con gcc, io uso il seguente:

/* 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

L'altro le risposte funzionano, ma è possibile evitare l'assemblaggio in linea utilizzando l'interfaccia intrinseca di GCC __rdtsc, disponibile includendo x86intrin.h.

+0

Va notato che l'effetto sarà praticamente lo stesso (ma molto più leggibile!), Poiché questo intrinseco ha tipicamente la firma "extern __inline unsigned long long __attribute __ ((__gnu_inline__, __always_inline__, __artificial__)) __rdtsc (vuoto) ', cioè sarà ancora in linea nel file binario risultante. – Joost