Skip to content

Instantly share code, notes, and snippets.

@stedolan
Created October 2, 2011 23:37
Show Gist options
  • Save stedolan/1258107 to your computer and use it in GitHub Desktop.
Save stedolan/1258107 to your computer and use it in GitHub Desktop.
Cache benchmarks
#include <time.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
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 );
}
#define NOINLINE __attribute__((noinline))
volatile int g;
typedef uint64_t u64;
#define REP10(x) x;x;x;x;x; x;x;x;x;x
#define REPCOUNT 20000
NOINLINE void bench(volatile u64* d){
volatile u64* p = d;
for (long i=0;i<REPCOUNT/100;i++){
REP10(REP10(p = (volatile u64*)(*p)););
}
}
NOINLINE char* mkperm(int n, int s){
char* d = malloc(n * s);
memset(d, 0, n * s);
int k = 0;
int l = 0;
int i;
while (k < n - 1){
i = rand() % n;
if ( *((u64**)(d + i*s)) == 0 && i != l){
*((u64**)(d + l*s)) = (u64*)(d + i*s);
l = i;
k++;
}
}
*((u64**)(d + l*s)) = (u64*)d;
return d;
}
static const uint64_t G = 1000ull*1000*1000;
int main(int argc, char* argv[]){
volatile u64** d = mkperm(/* atoi(argv[1]), 128 */);
struct timespec t1, t2;
// bench(d);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t1);
bench(d);
u64 r1 = rdtsc();
bench(d);
u64 r2 = rdtsc();
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &t2);
uint64_t t = ((uint64_t)(t2.tv_sec - t1.tv_sec)*G) + (t2.tv_nsec - t1.tv_nsec);
uint64_t cyclespersec = 2800ull * 1000 * 1000;
printf("%llu\n", (uint64_t)(0.5 + (double)(t) / (double)G * (double)(cyclespersec)));
printf("%llu\n", r2-r1);
printf("%.2f\n", (double)(r2-r1) / (double)REPCOUNT);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment