Author Topic: CPU speed (x86)  (Read 2849 times)

Ken Fitlike

  • Jackass V
  • Posts: 1568
  • Karma: +25/-22
  • Ebeneezer McScrooge
CPU speed (x86)
« on: April 08, 2005, 09:09:21 PM »
I was fiddling around with timers for some original reason that I've since forgotten - something to do with trying to find something accurate for both windows and linux but I think that platform specific solutions are probably better (QueryPerformanceCounter and QueryPerformanceFrequency for windows, gettimeofday for linux). Anyway for what it's worth, I did this which sort of does a cpu speed check but is not too accurate.
Code: [Select]
/*---------------------------------------------------------------------------*/
/*
  CPU SPEED using RDTSC asm instruction
  copyright (c) Ken Fitlike 2005
  Free to good home
  Disclaimer: Any problems you have with this code are just that:
              your problems.

  Notes:
  Function overhead seems insignificant when calculating cpu speed but should,
  ideally, be corrected for when attempting to use the highest resolution timer
  possible with this approach. The testing was not exhaustive ie. was limited
  to a single machine.

  Rejecting the lower 25% of multiple results of GetCPUSpeed results in a
  slight improvement in cpu speed accuracy when compared with, eg. results
  from wcpuid.

  RDTSC is non-serialising ie. it may not wait for all previous instructions
  to execute and may begin subsequent instructions prior to reading the
  counter. Thus, before its use the seralising cpuid is called; since the
  first call to cpuid is documented as slower than subsequent ones, three
  calls are made in an effort to 'normalise' behaviour.
*/
/*---------------------------------------------------------------------------*/
#include
#include
/*---------------------------------------------------------------------------*/
long long GetCPUSpeed()
{
unsigned int hiLowPart=0,hiHighPart=0;
unsigned int loLowPart=0,loHighPart=0;
unsigned long long start=0,end=0;
double t=0;
clock_t timer_start=0,timer_stop=0;

__asm__ ("xor %eax, %eax");
__asm__ ("xor %ebx, %ebx");
__asm__ ("xor %ecx, %ecx");
__asm__ ("xor %edx, %edx");
__asm__ ("cpuid");
__asm__ ("cpuid");
__asm__ ("cpuid");
__asm__ ("rdtsc": "=a"(hiLowPart), "=d"(hiHighPart));
     
timer_start=clock();

for (;;)
  {
  timer_stop=clock();
  if ((timer_stop-timer_start)>CLOCKS_PER_SEC)  /*1 second*/
    {
    __asm__ ("xor %eax, %eax");
    __asm__ ("xor %ebx, %ebx");
    __asm__ ("xor %ecx, %ecx");
    __asm__ ("xor %edx, %edx");
    __asm__ ("cpuid");
    __asm__ ("cpuid");
    __asm__ ("cpuid");
    __asm__ ("rdtsc": "=a"(loLowPart), "=d"(loHighPart));
    break;
    }
  }

/*this gets a more precise measure of that '1 second' interval above*/
t=(double)(timer_stop-timer_start)/(double)CLOCKS_PER_SEC;

start|=hiHighPart;
start<<=32;
start|=hiLowPart;

end|=loHighPart;
end<<=32;
end|=loLowPart;

/*ensure no div-by-zero error*/
t=t!=0?t:1;
return (end - start)/(unsigned long long)(1000000*t);
}
/*---------------------------------------------------------------------------*/
int main()
{
int i;
const int NUM=20;
long long speed=0,mean_speed=0;

printf("CPU Speed\n\n");
printf("%s%u\n\n","CLOCKS_PER_SEC: ",(unsigned int)CLOCKS_PER_SEC);

for (i=NUM;i>0;--i)
  {
  speed=GetCPUSpeed();
  mean_speed+=speed;
  printf("%d%s\n",(int)speed," MHz");
  }
printf("%s%d\n","Average cpu speed: ",(int)(mean_speed/NUM));
return 0;
}
/*---------------------------------------------------------------------------*/
And what rough beast, its hour come round at last,
Slouches towards Bethlehem to be born?.

jverkoey

  • Jackass III
  • Posts: 226
  • Karma: +12/-2
    • http://TheJeffFiles.com/
CPU speed (x86)
« Reply #1 on: April 14, 2005, 12:26:16 AM »
What compiler did you use for this?
-Jeff Verkoeyen

Ken Fitlike

  • Jackass V
  • Posts: 1568
  • Karma: +25/-22
  • Ebeneezer McScrooge
CPU speed (x86)
« Reply #2 on: April 14, 2005, 12:37:33 AM »
gcc.
And what rough beast, its hour come round at last,
Slouches towards Bethlehem to be born?.