Created
January 29, 2014 17:23
-
-
Save mikesart/8692706 to your computer and use it in GitHub Desktop.
clock overhead blurb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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