-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathtiming.h
69 lines (57 loc) · 1.87 KB
/
timing.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#ifndef TIMING_H
#define TIMING_H
#include <stdint.h> // needed to use uint64_t
#include <stdlib.h> // needed to use qsort()
#define NUM_TIMINGS (1LLU << 25)
#define OVERHEAD_LOOPS 1000000
uint64_t start_timer(void);
uint64_t end_timer(void);
uint64_t measure_overhead(void);
uint64_t start_timer(void)
{
int a, d;
__asm__ volatile("CPUID\n\t"
"RDTSC\n\t"
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t"
: "=r" (d), "=r" (a) // output operands
: // input operands (empty in this case)
: "%rax", "%rbx", "%rcx", "%rdx" // clobbered register
);
return ((uint64_t)a | (((uint64_t)d) << 32));
}
uint64_t end_timer(void)
{
int a, d;
__asm__ volatile("RDTSCP\n\t"
"mov %%edx, %0\n\t"
"mov %%eax, %1\n\t"
"CPUID\n\t"
: "=r" (d), "=r" (a) // output operands
: // input operands (empty in this case)
: "%rax", "%rbx", "%rcx", "%rdx" // clobbered register
);
return ((uint64_t)a | ((uint64_t)d << 32));
}
int compare_u64(const void *x, const void *y)
{
double xx = *(uint64_t*)x, yy = *(uint64_t*)y;
if (xx < yy) return -1;
if (xx > yy) return 1;
return 0;
}
// compute the measurement overhead
uint64_t measure_overhead(){
uint64_t *cycles = (uint64_t *)malloc(OVERHEAD_LOOPS * sizeof(uint64_t));
uint64_t temp;
for (uint64_t i = 0; i < OVERHEAD_LOOPS; i++){
temp = start_timer();
temp = end_timer() - temp;
cycles[i] = temp;
}
qsort(cycles, OVERHEAD_LOOPS, sizeof(uint64_t), compare_u64);
uint64_t output = cycles[OVERHEAD_LOOPS / 2];
free(cycles);
return output;
}
#endif