Skip to content

Instantly share code, notes, and snippets.

@mikesart
Created January 29, 2014 17:23
Show Gist options
  • Save mikesart/8692706 to your computer and use it in GitHub Desktop.
Save mikesart/8692706 to your computer and use it in GitHub Desktop.
clock overhead blurb
// clock_overhead
// (code started from http://stackoverflow.com/questions/6814792/why-is-clock-gettime-so-erratic)
#include <time.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <inttypes.h>
/* Compiled & executed with:
gcc clock_overhead.c -O0 -lrt -o clock_overhead
./clock_overhead
*/
static inline uint64_t rdtsc()
{
#if defined(__i386__)
uint64_t x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
#elif defined(__x86_64__)
uint32_t hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ((uint64_t)lo) | ((uint64_t)hi << 32);
#else
#error Unsupported architecture.
#endif
}
int main(int argc, char *argv[])
{
int i;
uint64_t tstart, tend;
struct timespec tstart2, tend2;
int N = (argc > 1) ? atoi(argv[1]) : 1000000;
#if defined(__i386__)
const char arch[] = "32-bit";
#elif defined(__x86_64__)
const char arch[] = "64-bit";
#else
const char arch[] = "??-bit";
#endif
printf("\n");
printf("Running estimated overhead tests on %s.\n", arch);
printf("\n");
printf("CPU model from /proc/cpuinfo:\n");
system("grep \"model name\" -m 1 /proc/cpuinfo");
for (i = 0; i < 10; i++)
{
int n;
printf("\n");
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tstart2);
tstart = rdtsc();
for (n = 0; n < N; ++n)
{
uint64_t dummy;
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
dummy = rdtsc();
}
tend = rdtsc();
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tend2);
printf("rdtsc : %3" PRIu64 " ns",
((uint64_t) tend2.tv_sec * 1000000000 + (uint64_t) tend2.tv_nsec
- ((uint64_t) tstart2.tv_sec * 1000000000
+ (uint64_t) tstart2.tv_nsec)) / N / 10);
printf(" %G cycles\n", (double)(tend - tstart)/N/10);
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tstart2);
tstart = rdtsc();
for (n = 0; n < N; ++n)
{
struct timespec dummy2;
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
clock_gettime(CLOCK_MONOTONIC, &dummy2);
}
tend = rdtsc();
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tend2);
printf("clock_gettime : %3" PRIu64 " ns",
((uint64_t) tend2.tv_sec * 1000000000 + (uint64_t) tend2.tv_nsec
- ((uint64_t) tstart2.tv_sec * 1000000000
+ (uint64_t) tstart2.tv_nsec)) / N / 10);
printf(" %G cycles\n", (double)(tend - tstart)/N/10);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment