just wondering if anyone has an example on how to measure the cpu speed? i have no idea how to do it. Thank you for any help.

- freedumb
Posted on 2001-12-10 15:12:29 by freedumb
found some delphi code that is very accurate on my system.
the gist of it is rdtsc with a realtime-thread.

function GetCPUSpeed: Double;
DelayTime = 500; // measure time in ms
TimerHi, TimerLo: DWORD;
PriorityClass, Priority: Integer;
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);

SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);

dw 310Fh // rdtsc
mov TimerLo, eax
mov TimerHi, edx
dw 310Fh // rdtsc
sub eax, TimerLo
sbb edx, TimerHi
mov TimerLo, eax
mov TimerHi, edx

SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);

Result := TimerLo / (1000.0 * DelayTime);

Here's a link for the exe / source
Posted on 2001-12-10 15:51:56 by grv575
That piece of code uses sleep. Sleep is not very accurate. Perhaps
it gets a bit better in a realtime thread, but still... nah.

Imho the best solution is to write a small block of code that will
take a fixed amount of cycles, and run it in a loop "enough times"
that "initial overhead" (etc) won't matter too much. If I understand
modern processors right, it might be a good idea to throw in a
serializing instruction such as CPUID.
Posted on 2001-12-10 16:20:47 by f0dder
f0dder, there is a block of code which takes a fixed amount of time on all processors? What is it?
Posted on 2001-12-10 16:38:53 by bitRAKE
i've tried doing serialzing cpuid / rdtsc in loops that get executed millions of times. it still gives varying results. even though sleep itself is inaccurate, that 10ms sleep before rdtsc seems to flush out the cache and give the same rdtsc count every time. i get
1398 mhz consistently on my 1.4Ghz system. Here's the asm translation of the code.
Posted on 2001-12-10 16:40:34 by grv575
bitRake: I guess that's the major problem ;). But a mix of NOPs and CPUIDs perhaps? ;).
Posted on 2001-12-10 16:44:29 by f0dder
; tasm32 /ml /m3 /z ws
; tlink32 -x /Tpe /aa /c /V4.0 /o ws,ws,, import32.lib
.Model Flat ,StdCall
Extrn _wsprintfA : near
include w32.inc


capt db 'CPU Test',0
format db 'CPU Speed = %lu Mhz',0
buffer db 30 dup (0)


xor eax,eax
db 0fh,31h ;rdtsc
mov ebx,eax
call Sleep, 1000
db 0fh,31h ;rdtsc
sub eax,ebx
sub eax,8
xor edx,edx
mov ecx,1000000
div ecx
call _wsprintfA, offset buffer, offset format, eax
call MessageBoxA, 0 ,offset buffer, offset capt, 0
call ExitProcess , 0

end main

but not work below 486 because rdtsc pentium opcode.

have nice day.

Posted on 2001-12-10 17:35:06 by CYDONIA
There have been great volumes of text wrote about this in the news group comp.lang.asm.x86
Posted on 2001-12-10 21:31:05 by bitRAKE
What you are looking for with timings is to flush the L1 cache before the timing is started, CPUID will do that. Then you workout the latency of RDTSC in ring3 or do it the crude and effective way by running a few calls to it in a row then clock your code.

In ring3 it will still wander due to OS interference so unless you want to write a device driver to do it, you are no better off. Thats why I use GetTickCount on big samples.

Getting the processor clock frequency is not really critical, just disregard the first few attempts, run it enough times and average it and you will be close enough.


Posted on 2001-12-11 00:22:22 by hutch--
it gives me the advertised speed of my machine too, or at least within 0.1%...
Posted on 2001-12-11 03:14:37 by peterverstappen
heh heh heh, you guys can all do it the hardcore way, but there is an easy way....

On NT based machines, the kernel has already done the work for you, you just gotta know where to find the info. The function GetSystemInfo will return quite a bit of info about the processor, but not the speed. To get the speed, check out the registry key:


there is a value under there called '~MHz' which contains the speed as a DWORD. Did you notice the '0' in the reg path above? If you have more than one processor, then you will have another key as '1' for the second processor, etc. :alright:
Posted on 2001-12-11 04:14:09 by sluggy
Hutch, if you set your thread priority to TimeCritical, there will not
be too much OS interference ;).
Posted on 2001-12-11 08:35:00 by f0dder
first RealtimePriorityClass,



Simple as that..

Posted on 2002-01-30 06:13:10 by Maverick

first RealtimePriorityClass,



If it wasn't clear for anybody, I implyed then also the use of RDTSC of course.

Posted on 2002-01-30 06:25:15 by Maverick
One of the best examples I've found explaining this is by Intel. The code is in C and Asm for both win16/32. I have only run it on Intel CPUs, so I'm not sure how it behaves with AMD. You can get it here:

Posted on 2002-02-01 11:47:43 by Shadow