2012-03-27 17 views
10

Z Visual Studio Mogę odczytać liczbę cykli zegara z procesora, jak pokazano poniżej. Jak zrobić to samo z GCC?licznik cykli z 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 

Odpowiedz

15

W najnowszych wersjach systemu Linux gettimeofday będzie zawierał nanosekundowe taktowania.

Jeśli naprawdę chcesz zadzwonić RDTSC można użyć następującego inline montaż:

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

Tak, naprawdę potrzebuję RDTSC, a teraz mam go. Dziękuję Ci. – user763305

+0

ten kod nie zawiera instrukcji serializacji, więc na każdym nowoczesnym procesorze (który jest poza kolejnością), przyniesie niepoprawne wyniki. zwykle używany jest cpuid. – markhahn

+0

Wersja 64-bitowa generuje słabe połączenie z gcc. Aby go poprawić, przesuń 'rdx' 32 bity w lewo i lub ręcznie za pomocą' rax'. Rezultatem jest "rax". –

5

On Linux z gcc, używam następujące:

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

Inny Odpowiedzi działają, ale można uniknąć wbudowanego zestawu przy użyciu wewnętrznego kodu GCC __rdtsc, dostępnego w tym x86intrin.h.

+0

Należy zauważyć, że efekt będzie prawie taki sam (ale o wiele bardziej czytelny!), Ponieważ nieodłączny typowo ma sygnaturę 'extern __inline unsigned long long __attribute __ ((__ gnu_inline__, __always_inline__, __artificial__)) __rdtsc (void) ', tzn. nadal będzie wstawiony w wynikowy plik binarny. – Joost