News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

CPU Frequency Program

Started by dedndave, August 06, 2009, 02:10:47 AM

Previous topic - Next topic

drizz

CPUFrequency proc cpu:dword

LOCAL Freq:LARGE_INTEGER, cntStart:LARGE_INTEGER, cntEnd:LARGE_INTEGER, tsc:LARGE_INTEGER

invoke GetCurrentThread
invoke SetThreadAffinityMask,eax,cpu
invoke QueryPerformanceFrequency,addr Freq
invoke QueryPerformanceCounter,addr cntStart
rdtsc
mov tsc.LowPart,eax
mov tsc.HighPart,edx
invoke Sleep,50
rdtsc
sub eax,tsc.LowPart
sbb edx,tsc.HighPart
mov tsc.LowPart,eax
mov tsc.HighPart,edx
invoke QueryPerformanceCounter,addr cntEnd
mov eax,cntEnd.LowPart
mov edx,cntEnd.HighPart
sub eax,cntStart.LowPart
sbb edx,cntStart.HighPart
mov cntEnd.LowPart,eax
mov cntEnd.HighPart,edx
fninit
fild cntEnd.QuadPart
push 1000000
fild dword ptr [esp]
fmul
fild Freq.QuadPart
fild tsc.QuadPart
fmul
fxch
fdiv
frndint
fistp dword ptr [esp]
pop eax
ret

CPUFrequency endp
The truth cannot be learned ... it can only be recognized.

dedndave

this is a preliminary version of what i have been working toward
i want to clean up the documentation and, perhaps, add a feature or two
in the mean time, it would be great to know if this hangs up on anyones machine
if so, i can adjust a few equates

JayPee

Works fine on my system - well done
Greetings From New Zealand
(Land of the Long White Cloud)

GregL

#33
Dave,

Yeah, that's pretty smooth on my system.  CPU usage is negligible. :U

DednDave CPU Frequency

CPU 0: Intel(R) Pentium(R) D CPU 3.20GHz MMX SSE3 Cores: 2

CPU Frequency: 3196.960115  MHz

Press any key to exit

sinsi

No crashes here, just a strange thing

DednDave CPU Frequency

CPU 0: Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz MMX SSSE3 Cores: 4

CPU Frequency: 2399.8145382399.676902

If I time it right when using edit>mark, the display goes a bit funny...
Light travels faster than sound, that's why some people seem bright until you hear them.

fearless

DednDave CPU Frequency

CPU 0: Intel(R) Core(TM)2 Quad  CPU   Q9550  @ 2.83GHz MMX SSE4.1 Cores: 4

CPU Frequency: 2838.725635  MHz

Press any key to exit
ƒearless

dedndave

thanks all
yes, Sinsi - that is one of the console window bugs i have been talking about
actually, i think i know how to fix it, or, at least, make it appear to be fixed - lol
i just forgot to put that fix in - i will add it
i tried to design this program so that the user could change affinity and priority using the task manager without messing up
i see that isn't perfect, either - i will have to look into it
for a time-base, i am using GetSystemTimeAsFileTime which doesn't seem like it ought to be very stable
that part seems ok, though

Strobe Raver

Works accurate for me. (Intel(R) Pentium(R) 4 CPU 3.20GHz MMX SSE3 Cores: 2)

Very good indeed  :cheekygreen:

dedndave

#38
this one should handle the select text a little better
there is no fixing the console window - only taming it slightly
if you mess around with it enough, you can always make it screw up
if you get it into a really screwed up state, you sometimes have to close and open a new window to get it right again
anyways - let me get this one documented so i can put the source up for you guys

EDIT - updated - see the next post

dedndave

ok - here we go
i added a couple features JUST FOR YOU, Hutch !!! - lol
you can use the arrow keys to change the resolution
you can use the R, G, B, I keys to change the colour
it seems to work very well - i look forward to responses (good or bad - lol)

hutch--

Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

dedndave


Rockoon

I didnt look over the code so don't know the technique.. but my observations just the same

Most CPU's these days run dynamic frequencies. When under high load they cycle full blast, but when there isnt much system load they step down to a smaller multiple of the base frequency. For example, my 2Ghz Dual Core AMD64 will step down to 1Ghz if its just sitting there mostly idle.

Because of this, I cannot imagine a sampling-based technique that will work reliably that also doesnt pump up the CPU usage to 100% and keep it there for a large number of cycles (long enough for the scheduler to hand time off to the cpu drivers which will step up the processor to max)
When C++ compilers can be coerced to emit rcl and rcr, I *might* consider using one.

dedndave

i went out of my way to minimize cpu usage
you can observe usage by running the task manager under the performance tab
i keep it low by "consuming" time through use of the Sleep api
during execution of Sleep, the system is free to run other programs or perform house-cleaning, as needed
some of the Sleep periods are used for measurement - others are there just to burn off time
for those periods that are used for measurement, they are preceeded and followed by rdtsc instructions to get clock counts
paired with the rdtsc instructions are GetSystemTimeAsFileTime calls to mark times
that way, the Sleep api is used to consume time, not measure it
here is a simplified version of the code at the heart of the measurement routine
just prior to this code, a single core is selected using SetProcessAffinityMask
after the measurement is complete, the function is used again to restore affinity
notice that the measurement Sleep interval is a variable
the program alternates between long and short intervals and calculates frequency using the deltas
that method minimizes errors due to overhead
the suplimentary amount of time is also consumed with another Sleep call so the total measurement period is always the same
also, there is a dead period between measurements
my current settings are:

total cycle time: 500 ms
    short period: 20 ms
     long period: 130 ms

;RDTSC core found and selected
;save the initial priority class

FMeas6: INVOKE  GetPriorityClass,
                CpuFrequencyData.hProc
        or      eax,eax
        jnz     FMeas7

        mov     eax,NORMAL_PRIORITY_CLASS

FMeas7: mov     CpuFrequencyData.PrioCls,eax

;elevate priority class

        INVOKE  SetPriorityClass,
                CpuFrequencyData.hProc,
                REALTIME_PRIORITY_CLASS

;elevate thread priority

        INVOKE  SetThreadPriority,
                CpuFrequencyData.hThrd,
                THREAD_PRIORITY_TIME_CRITICAL

;start with a fresh time-slice

        INVOKE  Sleep,
                0

;get the initial system time

        push    edx
        push    eax
        INVOKE  GetSystemTimeAsFileTime,
                esp
        mov     ebx,[esp]

;wait for it to change

FMeas8: INVOKE  GetSystemTimeAsFileTime,
                esp
        cmp     ebx,[esp]
        jz      FMeas8

;get the TSC start count

        xor     eax,eax
        cpuid
        rdtsc
        push    edx
        push    eax

;wait for the specified interval

        INVOKE  Sleep,
                CpuFrequencyData.StrtInt

;get the terminal system time

        push    edx
        push    eax
        INVOKE  GetSystemTimeAsFileTime,
                esp
        mov     ebx,[esp]

;wait for it to change

FMeas9: INVOKE  GetSystemTimeAsFileTime,
                esp
        cmp     ebx,[esp]
        jz      FMeas9

;get the TSC stop count

        xor     eax,eax
        cpuid
        rdtsc
        push    edx
        push    eax

;restore thread priority

        INVOKE  SetThreadPriority,
                CpuFrequencyData.hThrd,
                THREAD_PRIORITY_NORMAL

;restore priority class

        INVOKE  SetPriorityClass,
                CpuFrequencyData.hProc,
                CpuFrequencyData.PrioCls

ecube

can;t u just get the cpu speed from the registry or wmi? that would resolve the problem of smarter cpus slowin down at idle times. None the less thanks for the code, is quite useful.