2012-03-27 12 views
10

Mit Visual Studio kann ich die Taktzykluszahl vom Prozessor wie unten gezeigt lesen. Wie mache ich das gleiche mit GCC?Taktzyklus mit 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 

Antwort

15

In den letzten Versionen von Linux wird gettimeofday Nanosekunden-Timings enthalten.

Wenn Sie wirklich anrufen möchten RDTSC Sie folgende Inline-Assembly verwenden können:

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

Ja, ich brauche wirklich RDTSC, und jetzt habe ich es. Vielen Dank. – user763305

+0

diesem Code fehlt eine Serialisierungsanweisung, so auf jedem modernen Prozessor (der nicht in der Reihenfolge ist), wird es falsche Ergebnisse liefern. normalerweise wird cpuid verwendet. – markhahn

+0

Die 64-Bit-Version erzeugt eine schlechte Assembly mit gcc. Um es zu verbessern, verschiebe 'rdx' 32 Bits nach links und oder mit' rax' manuell. Das Ergebnis ist in 'rax'. –

5

Unter Linux mit gcc, verwende ich die folgende:

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

Die andere Antworten funktionieren, aber Sie können Inline-Assembly vermeiden, indem Sie __rdtsc intrinsische GCC verwenden, die durch das Einschließen vonverfügbar sind.

+0

Es sollte beachtet werden, dass der Effekt wird fast das gleiche (aber viel besser lesbar!), Da diese intrinsische hat typischerweise die Signatur 'extern __inline unsigned lange lange __attribute __ ((__ gnu_inline__, __always_inline__, __artificial__)) __rdtsc (void) ', dh es wird immer noch in der resultierenden Binärdatei eingezeichnet. – Joost