summaryrefslogtreecommitdiff
path: root/bench/MHz.c
diff options
context:
space:
mode:
authorDave Jones <davej@redhat.com>2008-07-02 13:51:37 -0400
committerDave Jones <davej@redhat.com>2008-07-02 13:51:37 -0400
commit48c773f4c03a6b83370682d23217dcabb7e51d50 (patch)
treeb4e325e967014ce43fa7d7e57f2a490ab7e4405a /bench/MHz.c
parent89fbc7d42b1bb9bc2166de534ddd00ff903a4abe (diff)
Improve MHz estimation.
The fatal flaw was that rdtsc was wrapping too soon as we were only using 32bits of accuracy. Extending this to 64bit increases the resolution of the timing dramatically. We can also do away with all the other timing code as a bonus.
Diffstat (limited to 'bench/MHz.c')
-rw-r--r--bench/MHz.c37
1 files changed, 14 insertions, 23 deletions
diff --git a/bench/MHz.c b/bench/MHz.c
index 87315a9..187aa28 100644
--- a/bench/MHz.c
+++ b/bench/MHz.c
@@ -17,11 +17,14 @@
#include "../x86info.h"
-static unsigned long long int rdtsc(void)
+static inline unsigned long long int rdtsc(void)
{
- unsigned long long int x;
- __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
- return x;
+ unsigned int low, high;
+ unsigned long tsc;
+
+ __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high));
+ tsc = ((unsigned long long) high << 32) | low;
+ return tsc;
}
static volatile int nosignal = 0;
@@ -34,13 +37,9 @@ static void sighandler(int sig __attribute__((unused)))
void estimate_MHz(struct cpudata *cpu)
{
cpu_set_t set;
- struct timezone tz;
- struct timeval tvstart, tvstop;
unsigned long long int cycles[2]; /* gotta be 64 bit */
- unsigned long microseconds; /* total time taken */
unsigned int eax, ebx, ecx, edx;
- unsigned long freq = 1;
- unsigned long i;
+ unsigned long r;
/* Make sure we have a TSC (and hence RDTSC) */
cpuid(cpu->number, 1, &eax, &ebx, &ecx, &edx);
@@ -50,8 +49,6 @@ void estimate_MHz(struct cpudata *cpu)
return;
}
- memset(&tz, 0, sizeof(tz));
-
if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
CPU_ZERO(&set);
CPU_SET(cpu->number, &set);
@@ -64,25 +61,19 @@ void estimate_MHz(struct cpudata *cpu)
}
cycles[0] = rdtsc();
- gettimeofday(&tvstart, &tz);
- alarm(3);
- while (!nosignal) {
- i = i * rand();
- }
+ alarm(1);
+ while (!nosignal)
+ r = r * rand();
- cycles[1] = rdtsc();
- gettimeofday(&tvstop, &tz);
+ nosignal = 0;
- microseconds = ((tvstop.tv_sec-tvstart.tv_sec)*1000000) +
- (tvstop.tv_usec-tvstart.tv_usec);
+ cycles[1] = rdtsc();
- cpu->MHz = (int) (cycles[1]-cycles[0]) / (microseconds/freq);
+ cpu->MHz = (cycles[1] - cycles[0]) / 1000000;
if ((cpu->MHz % 50) > 15)
cpu->MHz = ((cpu->MHz / 50) * 50) + 50;
else
cpu->MHz = ((cpu->MHz / 50) * 50);
-
- nosignal = 0;
}