Originally Posted by
Click_here
Code:
#include "cycle_counting.h"
Okay... You can keep your secretes :P
No secret at all... nobody, yet, had the curiosity to ask me about this. Here's the code to measure clocks on SandyBridge and above processors (Intel) and most AMD ones, as well on ARM AArch64:
Code:
/* cycle_counting.h */
#ifndef CYCLE_COUNTING_INCLUDED__
#define CYCLE_COUNTING_INCLUDED__
#ifndef __GNUC__
# error Works only on GCC
#endif
/* ==========================================
Quick & Dirty cycle counting...
Usage:
counter_T cnt;
cnt = BEGIN_TSC();
f();
END_TSC(&cnt);
For i386 and x86-64 you can define SYNC_MEM if want a better
processor serialization before measuring the cycles (requires SSE2).
========================================== */
#include <stdint.h>
// Non volatitle to avoid optimizations.
typedef volatile uint64_t counter_T;
#if defined(__x86_64__)
inline counter_T BEGIN_TSC( void )
{
uint32_t a, d;
__asm__ __volatile__ (
# ifdef SYNC_MEM
"mfence\n\t"
# endif
"xorl %%eax,%%eax\n\t"
"cpuid\n\t"
"rdtsc" : "=a" (a), "=d" (d) :: "%rbx", "%rcx"
);
return a | ((uint64_t)d << 32);
}
inline void END_TSC( counter_T *cptr )
{
uint32_t a, d;
__asm__ __volatile__ (
"rdtscp" : "=a" (a), "=d" (d) :: "%rcx"
);
*cptr = (a | ((uint64_t)d << 32)) - *cptr;;
}
#elif defined(__i386__)
inline counter_T BEGIN_TSC( void )
{
uint32_t a, d;
__asm__ __volatile__ (
// mfence available only to SSE2 and above.
# ifdef __SSE2__
# ifdef SYNC_MEM
"mfence\n\t"
# endif
# endif
"xorl %%eax,%%eax\n\t"
"cpuid\n\t"
"rdtsc" : "=a" (a), "=d" (d) :: "%ebx", "%ecx"
);
return a | ((uint64_t)d << 32);
}
inline void END_TSC( counter_T *cptr )
{
uint32_t a, d;
__asm__ __volatile__ (
"rdtscp" : "=a" (a), "=d" (d) :: "%ecx"
);
*cptr = (a | ((uint64_t)d << 32)) - *cptr;
}
#elif defined(__aarch64__)
inline counter_T BEGIN_TSC( void )
{
uint64_t count;
__asm__ __volatile__ (
# ifdef SYNC_MEM
"dmb\n\t"
# endif
"mrs %0,cntvct_el0" : "=r" (count) );
return count;
}
inline void END_TSC( counter_T *cptr )
{
uint64_t count;
__asm__ __volatile__ ( "mrs %0,cntvct_el0" : "=r" (count) );
*cptr = count - *cptr;
}
#else
# error i386, x86-64 and AArch64 only.
#endif
#endif