Why does my compiler give me the err-msg: "Not allowed in current CPU mode" when I try to compile the cmd rdtsc? When I hard-code the opcode using "dw 310F" instead of "rdtsc" it works (no compiler error, no errors during execution)...
Does anyone know what intel centrino processors do with the "rdtsc" cmd? I wrote a cpu speed test (using rdtsc) that works fine on all processors - except my new centrino....!?

Dominik
Posted on 2005-01-21 12:56:44 by Dom
try ".586p" rather than ".386" or whatever.
Posted on 2005-01-21 13:53:19 by f0dder
Does anyone know what intel centrino processors do with the "rdtsc" cmd? I wrote a cpu speed test (using rdtsc) that works fine on all processors - except my new centrino....!?
Dominik


RDTSC has been in X86 processors since the Pentium.
Posted on 2005-01-21 23:53:33 by mark_larson
i didnt dubl post
Posted on 2005-01-22 03:20:42 by Retsim_X
yes,

i think the centrino's are a bit like the celeron's
they are missing some of the instruction set, lol
thats why they are cheap...

Retsim :lol:
Posted on 2005-01-22 03:20:58 by Retsim_X

Does anyone know what intel centrino processors do with the "rdtsc" cmd? I wrote a cpu speed test (using rdtsc) that works fine on all processors - except my new centrino....!?

How "doesn't it work"? If it gives wrong results, it's probably because of power-saving mode... you should use high-performance timers instead of rdtsc.
Posted on 2005-01-22 03:28:22 by f0dder
The following code seems to work fine but gives sh**ty results on my centrino...it used to be a 1.6Ghz, the result of the code differs between 25 and 200 Mhz...!?

p.s. to f0dder: you were right, .586 instead of .386 solves the compiler problem :)

DELAY_TIME is set to 1000...


GetCPUSpeed proc
LOCAL PriorityClass:DWORD
LOCAL Priority:DWORD
LOCAL cProcess:DWORD
LOCAL cThread:DWORD
LOCAL TimerVal:DWORD

invoke GetCurrentProcess
mov cProcess, eax
invoke GetPriorityClass, eax
mov PriorityClass, eax

invoke GetCurrentThread
mov cThread, eax
invoke GetThreadPriority, eax
mov Priority, eax

invoke SetPriorityClass, cProcess, REALTIME_PRIORITY_CLASS
invoke SetThreadPriority, cThread, THREAD_PRIORITY_TIME_CRITICAL
invoke Sleep, 10d

rdtsc ;dw 310Fh
mov ebx, eax
invoke Sleep, DELAY_TIME
rdtsc ;dw 310Fh
sub eax, ebx
mov TimerVal, eax

invoke SetThreadPriority, cThread, Priority
invoke SetPriorityClass, cProcess, PriorityClass

mov eax, DELAY_TIME
mov ecx, 1000d
mul ecx
mov ecx, eax
mov eax, TimerVal
xor edx, edx
div ecx
ret
GetCPUSpeed endp
Posted on 2005-01-22 04:46:37 by Dom
Hello,

I don't know if it could help but you should use CPUID to ensure serialization of instruction before using RDTSC. Without it it could sometimes give strange result on a short sequence of instructions.

BTW this is not the case in your code,since the use of an API give a great number of instruction processed...
Posted on 2005-01-22 07:43:23 by Neitsa
Dom,

You will always have the problem timing code in ring3 that the OS interferes with the timing so you are best to set up timings for at least a half a second or longer to reduce the error to under 1% or so. RDTSC is fine in ring0 as nothing interferes with it but unless you want to write a driver to do your testing, just run the test long enough with the priority control you are using and you will get reliable results.
Posted on 2005-01-22 07:50:55 by hutch--
To Neitsa: found another "GetCPUSpeed" source that included "xor eax, eax" and "cpuid" before executing "rdtsc". But the results are the same...
To hutch: I increased DELAY_TIME and let the test run over 10 seconds, same results.....
What about the APIs GetPerformanceFrequency & GetPerformanceCounter!?

Dominik
Posted on 2005-01-22 08:04:36 by Dom
Dom,

I time code with GetTickCount() in millisecond resolution as ring3 removes any additional advantage in terms of precision due to OS interference.
Posted on 2005-01-22 08:53:20 by hutch--
I've a question about the time stamp counter.

Since windows is not 'really' multi-threaded but handle process in a round-robin fashion, each time a time-slice occurs, the process and its thread states are saved. Then the O.S cycle through all process. Finally it came back to the process which use RDTSC.

So, does the time stamp counter continue to increment when the process has been saved (and therefore is freezed in a known state) ?
Posted on 2005-01-22 11:00:37 by Neitsa
Dom,

I time code with GetTickCount() in millisecond resolution as ring3 removes any additional advantage in terms of precision due to OS interference.


I thought that the resolution of GetTickCount was somewhere around 16 ms at is best, isn't it?
Posted on 2005-01-22 11:11:21 by lifewire
Dom,

I time code with GetTickCount() in millisecond resolution as ring3 removes any additional advantage in terms of precision due to OS interference.


That's why you need to set the priority class. I use RDTSC and this trick to get the same numbers every time I run the code. ( I also subtract out loop overhead). Having timing code that produces the same number every run is important to accurate timing. I avoid GetTickCount like the plague due to how inaccurate it is.



invoke GetCurrentProcess
invoke SetPriorityClass,eax,REALTIME_PRIORITY_CLASS
Posted on 2005-01-22 19:50:18 by mark_larson

The following code seems to work fine but gives sh**ty results on my centrino...it used to be a 1.6Ghz, the result of the code differs between 25 and 200 Mhz...!?

Again, my best bet is that it's because of power-saving mode that decreases the CPU frequency?
Posted on 2005-01-23 06:09:18 by f0dder
From testing over a number of years, ring3 timing is at best about 3% on smaller samples and gets worse as they get smaller. Once you set a duration over about half a second, you get results that are down around 1% which is hard to improve on. You can perform timings at ring0 but its a lot more work and it does not properly represent the performance in ring3 so there is no real gain there.
Posted on 2005-01-23 06:19:07 by hutch--
You can do accurate timing from ring3 as well, read this thread.
Posted on 2005-01-23 06:23:00 by f0dder