2012-03-27 24 views
10

Con Visual Studio, puedo leer el recuento de ciclo de reloj del procesador como se muestra a continuación. ¿Cómo hago lo mismo con GCC?recuento de ciclos de reloj 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 

Respuesta

15

En versiones recientes de Linux, gettimeofday incorporará temporizaciones de nanosegundos.

Si realmente desea llamar RDTSC se puede utilizar el siguiente ensamblado en línea:

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í, realmente necesito RDTSC, y ahora lo tengo. Gracias. – user763305

+0

este código carece de una instrucción de serialización, por lo que en cualquier procesador moderno (que esté fuera de servicio), dará resultados incorrectos. usualmente se usa cpuid. – markhahn

+0

La versión de 64 bits genera un ensamblaje deficiente con gcc. Para mejorarlo, cambie 'rdx' 32 bits a la izquierda y/o con' rax' manualmente. El resultado es en 'rax'. –

5

en Linux con gcc, utilizo el siguiente:

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

El otro las respuestas funcionan, pero puede evitar el ensamblaje en línea usando el intrínseco __rdtsc de GCC, disponible al incluir x86intrin.h.

+0

Debe notarse que el efecto será más o menos el mismo (pero mucho más legible), ya que este intrínseco típicamente tiene la firma 'extern __inline unsigned long long __tributo __ ((__gnu_inline__, __always_inline__, __rdificial__)) __rdtsc (void) ', es decir, seguirá insertado en el binario resultante. – Joost