The MASM Forum

General => The Laboratory => Topic started by: dedndave on October 13, 2015, 08:34:58 PM

Title: GetCpuFrequency Tests
Post by: dedndave on October 13, 2015, 08:34:58 PM
let's see how this runs on different machines   :P

EDIT: final version attached
Title: Re: GetCpuFrequency Tests
Post by: sinsi on October 13, 2015, 09:11:18 PM
 :t
Quote
0 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: nidud on October 13, 2015, 09:53:59 PM
deleted
Title: Re: GetCpuFrequency Tests
Post by: hutch-- on October 13, 2015, 09:59:05 PM
On my old i7,


0 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: jj2007 on October 13, 2015, 10:09:07 PM
0 kHz on i5, Win7-64
Title: Re: GetCpuFrequency Tests
Post by: Siekmanski on October 13, 2015, 10:24:19 PM
Intel(R) Core(TM) i7-4930K CPU @ 3.40GHz Windows 8.1

53157 KHz
Title: Re: GetCpuFrequency Tests
Post by: TouEnMasm on October 14, 2015, 12:00:24 AM
win 10
black screen ...black screen,is it slow ??
Title: Re: GetCpuFrequency Tests
Post by: mabdelouahab on October 14, 2015, 12:33:11 AM
i5 / Win8.1 x64
0 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: FORTRANS on October 14, 2015, 12:37:01 AM
Hi,

P-III 800 MHz.

12528 KHz

Pentium M 1.76 G

9727 KHz

Press any key to continue ...

Regards,

Steve
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 14, 2015, 12:50:16 AM
i can see i have some work to do on that one   :lol:

thanks guys  :t
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 14, 2015, 03:37:51 AM
ok - i found the math error - (subtracted from EDI when it should have been from ECX - lol)

now, i will have to isolate the reason for the 0 results
there are a few possible causes, so i will add some sort of report code to isolate the problem
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 14, 2015, 05:21:50 AM
ok - new post at top of thread
i appreciate your help, guys   :t

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3000218 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: TWell on October 14, 2015, 05:34:11 AM
Processor: AMD Athlon(tm) II X2 220 Processor (2 CPUs), ~2.8GHz
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2800001 KHz
Title: Re: GetCpuFrequency Tests
Post by: nidud on October 14, 2015, 05:37:34 AM
deleted
Title: Re: GetCpuFrequency Tests
Post by: nidud on October 14, 2015, 05:46:57 AM
deleted
Title: Re: GetCpuFrequency Tests
Post by: FORTRANS on October 14, 2015, 05:48:16 AM
Hi,

P-III

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
801818 KHz

Press any key to continue ...

Pentium M

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
632730 KHz

Press any key to continue ...

HTH,

Steve N.
Title: Re: GetCpuFrequency Tests
Post by: Siekmanski on October 14, 2015, 06:34:04 AM
Intel(R) Core(TM) i7-4930K CPU @ 3.40GHz Windows 8.1

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
3402080 KHz
Title: Re: GetCpuFrequency Tests
Post by: jj2007 on October 14, 2015, 06:51:19 AM
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 KHz

And no errors reported by GetLastError ::)
Title: Re: GetCpuFrequency Tests
Post by: sinsi on October 14, 2015, 06:53:14 AM
Numbers 0-13 show straight away, then a wait for 14,15, speed=0
AMD A10-7850 3.70 GHz, Windows 7 Ultimate x64

edit: Same thing for i7-4790 3.60 GHz, Windows 10 Pro
Title: Re: GetCpuFrequency Tests
Post by: nidud on October 14, 2015, 07:30:08 AM
deleted
Title: Re: GetCpuFrequency Tests
Post by: hutch-- on October 14, 2015, 08:08:37 AM
No luck on my old i7.


0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 14, 2015, 08:44:17 AM
dang - back to the drawing board
the one that makes me scratch my head is 22 KHz - lol
the 0's are a bit of a mystery, too - but one that probably has a simple fix that i am overlooking

thanks again, guys   :t
Title: Re: GetCpuFrequency Tests
Post by: mabdelouahab on October 14, 2015, 08:53:45 AM
i5 / Win8.1 x64
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 14, 2015, 02:39:11 PM
yah - i have some work to do - lol

thought i had the bases covered
makes me feel like a novice   :(
Title: Re: GetCpuFrequency Tests
Post by: Raistlin on October 14, 2015, 04:09:19 PM
Intel Core i5 HP Prodesk

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 KHz

Press any key to continue ...


@Dave - thanks for personal mail btw
Title: Re: GetCpuFrequency Tests
Post by: TouEnMasm on October 15, 2015, 01:48:31 AM
Intel(R) Core(TM) i3-4150 CPU @ 3.50GHz
Microsoft Windows 10 Famille Version: 10.0.10240
-----------------------------------------------------------------------------------------------------------------
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 KHz
-------------------------------------------------------------------------------------------------------------------
Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: TouEnMasm on October 15, 2015, 01:59:42 AM
Perhaps a stupid question,why not used cpuid instruction to get the frequency
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 15, 2015, 02:04:56 PM
that is the "design" frequency - the frequency that the manufacturer intended the processor to be used
i want to measure the actual clock frequency

honestly, i thought this would be easy - lol
in the old forum, Edgar came up with some code (and i wrote a program using it)
it seemed to work fairly well
however, that was before windows 8 and 10 (and newer processors, i guess)
also, i am doing some things differently

at the moment, i am time limited
my mom is in the hospital, and i have been spending every night with her
so - i get some time during the day, but i am somewhat exhausted - probably the reason for the errors   :P
Title: Re: GetCpuFrequency Tests
Post by: FORTRANS on October 15, 2015, 11:36:15 PM
Hi Dave,

Quote from: dedndave on October 15, 2015, 02:04:56 PM
that is the "design" frequency - the frequency that the manufacturer intended the processor to be used
i want to measure the actual clock frequency

   Makes sense.  I guess it is accuracy that would make things
tricky.  A rough estimate with an ugly spread should be easy?

Quoteat the moment, i am time limited
my mom is in the hospital, and i have been spending every night with her
so - i get some time during the day, but i am somewhat exhausted - probably the reason for the errors

   Sorry to hear that.  I hope things are getting better.

Best of luck,

Steve N.
Title: Re: GetCpuFrequency Tests
Post by: MichaelW on October 16, 2015, 07:54:05 PM
Running on my POS Windows 8.1-64 laptop, with a 2.16GHz Celeron, I get:

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 KHz


For a laptop I was expecting the clock speed to vary a lot, so in my code I did everything I could think of to maximize the resolution and accuracy, and surprisingly the variation is limited to the 6th decimal place.


;===============================================================================
include \masm32\include\masm32rt.inc
.686
;===============================================================================
.data
      pf      LARGE_INTEGER <>
      pc1     LARGE_INTEGER <>
      pc2     LARGE_INTEGER <>
      cc1     LARGE_INTEGER <>
      cc2     LARGE_INTEGER <>
      giga    REAL8 1000000000.0
      freq    REAL8 ?
.code   
;=============================================================================== 
start:
;===============================================================================

    invoke GetCurrentProcess
    mov     ebx, eax
   
    invoke SetProcessAffinityMask, ebx, 1
    invoke SetPriorityClass, ebx, REALTIME_PRIORITY_CLASS
   
    invoke GetCurrentThread
    invoke SetThreadPriority, eax, THREAD_PRIORITY_TIME_CRITICAL
   
    invoke Sleep, 2000
   
    invoke QueryPerformanceFrequency, ADDR pf
    ;printf("%I64d\n\n",pf.QuadPart)
   
    xor     eax, eax
    cpuid
    rdtsc
    mov     cc1.HighPart, edx
    mov     cc1.LowPart, eax
   
    invoke QueryPerformanceCounter, ADDR pc1

    invoke Sleep, 2000
   
    xor   eax, eax
    cpuid
    rdtsc
    mov     cc2.HighPart, edx
    mov     cc2.LowPart, eax

    invoke QueryPerformanceCounter, ADDR pc2
   
    ; elapsed counter cycles = pc2.QuadPart - pc1.QuadPart
    ; elapsed seconds = elapsed counter cycles / pf.QuadPart
    ; elapsed clock cycles = cc2.QuadPart - cc1.QuadPart
    ; clock speed = elapsed cycles / elapsed seconds
   
    fild    pc2.QuadPart
    fild    pc1.QuadPart
    fsub
    fild    pf.QuadPart
    fdiv
    fild    cc2.QuadPart
    fild    cc1.QuadPart
    fsub
    fdivr
    fld     giga
    fdiv
    fstp    freq

    printf("%fGHz\n\n", freq)   
   
    inkey
    exit
end start
;===============================================================================

Title: Re: GetCpuFrequency Tests
Post by: jj2007 on October 16, 2015, 08:58:51 PM
Since I've not yet fully understood the meaning of the results, I rolled my own:
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
Heating up...
RDTSC in ... out, 2.552 GHz
RDTSC in ... out, 2.517 GHz
RDTSC in ... out, 2.518 GHz
RDTSC in ... out, 2.536 GHz
RDTSC in ... out, 2.542 GHz


Intel(R) Celeron(R) CPU  N2840  @ 2.16GHz
Heating up...
RDTSC in ... out, 2.201 GHz
RDTSC in ... out, 2.202 GHz
RDTSC in ... out, 2.201 GHz
RDTSC in ... out, 2.204 GHz
RDTSC in ... out, 2.203 GHz

Title: Re: GetCpuFrequency Tests
Post by: Farabi on October 16, 2015, 11:20:29 PM
Why not meassure it in direct memory transfer within looping in 1 gigs loop. It  will force the vendor design better.

mov ecx,some_pointer

mov ecx,1000000000
break_vendor_credibilitty:
mov eax,[some_pointer]
jecxz break_vendor_credibility


:greenclp:
Title: Re: GetCpuFrequency Tests
Post by: TWell on October 16, 2015, 11:29:16 PM
AMD 2.8 GHz
AMD Athlon(tm) II X2 220 Processor
Heating up...
RDTSC in ... out, 2.807 GHz
RDTSC in ... out, 2.901 GHz
RDTSC in ... out, 2.851 GHz
RDTSC in ... out, 2.817 GHz
RDTSC in ... out, 2.894 GHz
with simple versionRDTSC in ... out, 2.903 GHz
RDTSC in ... out, 2.868 GHz
RDTSC in ... out, 2.831 GHz
RDTSC in ... out, 2.823 GHz
RDTSC in ... out, 2.858 GHz

.686
.model flat,stdcall

ExitProcess PROTO :DWORD
GetTickCount PROTO
INCLUDELIB kernel32.lib

printf PROTO CDECL :VARARG
INCLUDELIB msvcrt.lib

.data
msg1 DB "RDTSC in ... ",0
msg2 DB "out",0
msg3 DB ", %4.3f GHz",13,10,0
m1 QWORD 0.000000001
pf QWORD ?

.code
main PROC
xor ecx, ecx
.Repeat
inc ecx
.Until Sign?
REPEAT 5
invoke printf, addr msg1
cpuid
rdtsc
push edx
push eax
invoke GetTickCount
add eax, 1000 ; one second
push eax
xor esi, esi
.Repeat
inc esi
test esi, 0ffffffh
.if Zero?
invoke GetTickCount ; ca. 93 calls per run
.endif
.Until eax>[esp]
pop edx
invoke printf, offset msg2
rdtsc
push edx
push eax
fild qword ptr [esp]
add esp, qword
fild qword ptr [esp]
add esp, qword
fsub
fmul qword ptr m1
fst pf
invoke printf, offset msg3, pf
ENDM
INVOKE ExitProcess,0
main ENDP
END main
Title: Re: GetCpuFrequency Tests
Post by: FORTRANS on October 17, 2015, 12:28:36 AM
Hi,

   Doesn't work on the P-III as expected.  Here are the Pentium M
results.  First to screen, second redirected to a file.

Intel(R) Pentium(R) M processor 1.70GHz
Heating up...
RDTSC in ... out, 1.705 GHz
RDTSC in ... out, 1.704 GHz
RDTSC in ... out, 1.736 GHz
RDTSC in ... out, 1.732 GHz
RDTSC in ... out, 1.721 GHz

Intel(R) Pentium(R) M processor 1.70GHz
Heating up...
RDTSC in ... out, 1.702 GHz
RDTSC in ... out, 1.708 GHz
RDTSC in ... out, 1.705 GHz
RDTSC in ... out, 1.706 GHz
RDTSC in ... out, 1.706 GHz


Regards,

Steve N.
Title: Re: GetCpuFrequency Tests
Post by: Siekmanski on October 17, 2015, 01:34:02 AM
Intel(R) Core(TM) i7-4930K CPU @ 3.40GHz
Heating up...
RDTSC in ... out, 3.439 GHz
RDTSC in ... out, 3.440 GHz
RDTSC in ... out, 3.473 GHz
RDTSC in ... out, 3.440 GHz
RDTSC in ... out, 3.474 GHz
Title: Re: GetCpuFrequency Tests
Post by: HSE on October 17, 2015, 03:16:15 AM
Hi Dave!


Doszip Macro Assembler Version 2.14, BETA  09/11/15
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.

Assembling: Getcpufrequency.asm

***********
ASCII build
***********

Getcpufrequency.asm(138) : error A2084: constant value too large
_
Assembly Error
Presione una tecla para continuar . . .



JWasm v2.13, Aug  8 2015, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.


***********
ASCII build
***********

GetCpuFrequency.asm(138) : Error A2239: Constant value too large: 1F4000000h
GetCpuFrequency.asm: 466 lines, 1 passes, 136 ms, 0 warnings, 1 errors


Modification:
__CountExponent = 22

Results:


AMD A6-3500 APU with Radeon(tm) HD Graphics

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
0 KHz

Press any key to continue ...

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1 KHz

Press any key to continue ...



Modification:
__CountExponent = 12

Result:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2101141 KHz



__CountExponent = 8

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
2859 KHz



AMD A6-3500 APU with Radeon(tm) HD Graphics
Heating up...
RDTSC in ... out, 2.124 GHz
RDTSC in ... out, 2.120 GHz
RDTSC in ... out, 2.202 GHz
RDTSC in ... out, 2.157 GHz
RDTSC in ... out, 2.142 GHz

Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 17, 2015, 03:51:40 AM
1 SHL 23 is 1000 0000 0000 0000 0000 0000 binary, or 800000h - that should fit in 32 bits   :redface:
Title: Re: GetCpuFrequency Tests
Post by: HSE on October 17, 2015, 04:34:01 AM
Ok. Ml compile with 1 SHL 23, but result  0 Khz. Work well with 1 SHL 12 (and others like 18).
Title: Re: GetCpuFrequency Tests
Post by: nidud on October 17, 2015, 04:57:02 AM
deleted
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 17, 2015, 10:59:55 AM
thanks HSE and nidud - that is definately a bug that i missed   :t
it probably happened, as i increased the __CountExponent, without checking the range of 1000X - oops

that does solve a few problems - like the case where the routine takes too long
it doesn't make sense to me that it causes a 0 result, though - have to look into that   :redface:
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 17, 2015, 03:02:35 PM
that one was easy to fix

            mov     edx,_dwQPFreqHi
            mov     eax,__CountLength
            mov     ebx,_dwQPFreqLo
            bsr     ecx,edx
            .if !ZERO?
                inc     ecx
                shrd    ebx,edx,cl
                adc     ebx,0
                xor     edx,edx
                shr     eax,cl
                adc     eax,edx
            .endif
            .if ebx
                mov     edx,1000
                mul     edx
                div     ebx


load the unmultiplied value - then MUL by 1000 just before DIV
Title: Re: GetCpuFrequency Tests
Post by: HSE on October 18, 2015, 09:46:55 AM
Ok with __CountExponent = 20
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 18, 2015, 03:00:37 PM
ok - ready to try again.....

QueryPerformanceFrequency: 00000000_B2D0FA40h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00240010h
              dwSleepTime: 1
             dwMultiplier: 1536020480
                 Measured: 8389545, 8389215, 8388772, 8389125, 8389433
                   Sorted: 8388772, 8389125, 8389215, 8389433, 8389545

          GetCpuFrequency: 3000241 KHz

Press any key to continue ...


test program and source attached...
Title: Re: GetCpuFrequency Tests
Post by: sinsi on October 18, 2015, 03:24:57 PM

QueryPerformanceFrequency: 00000000_00342787h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00240010h
              dwSleepTime: 2451
             dwMultiplier: 1750011
                 Measured: 890, 1006, 166412, 879, 1019
                   Sorted: 879, 890, 1006, 1019, 166412

          GetCpuFrequency: 0 KHz

Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 18, 2015, 03:28:19 PM
thanks John   :t

guess i have to re-think that calculation, altogether   :lol:
Title: Re: GetCpuFrequency Tests
Post by: Siekmanski on October 18, 2015, 05:53:27 PM
QueryPerformanceFrequency: 00000000_00DA7A64h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00240010h
              dwSleepTime: 583
             dwMultiplier: 7330908
                 Measured: 1993179744, 1993179680, 1993180756, 1993181674, 1993181084
                   Sorted: 1993179680, 1993179744, 1993180756, 1993181084, 1993181674

          GetCpuFrequency: 3402081 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: TWell on October 18, 2015, 06:55:27 PM
AMD 2.8 GHz
AMD Athlon(tm) II X2 220 Processor
QueryPerformanceFrequency: 00000000_00DA7A64h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00240010h
              dwSleepTime: 583
             dwMultiplier: 7330908
                 Measured: 1640441959, 1640437624, 1640440917, 1640440083, 16404
39766
                   Sorted: 1640437624, 1640439766, 1640440083, 1640440917, 16404
41959

          GetCpuFrequency: 2800001 KHz
Title: Re: GetCpuFrequency Tests
Post by: TWell on October 18, 2015, 08:10:05 PM
AMD E450 1.65 GHzQueryPerformanceFrequency: 00000000_00188916h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00240010h
              dwSleepTime: 5214
             dwMultiplier: 823274
                 Measured: 817, 1045, 459, 846, 903
                   Sorted: 459, 817, 846, 903, 1045

          GetCpuFrequency: 0 KHz
AMD 1,35 GHzQueryPerformanceFrequency: 00000000_00141434h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00240010h
              dwSleepTime: 6372
             dwMultiplier: 673737
                 Measured: 560, 808, 924, 371, 944
                   Sorted: 371, 560, 808, 924, 944

          GetCpuFrequency: 0 KHz
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 19, 2015, 07:03:22 PM
thanks again, guys   :t

that gives me enough data to fix the problems - lol
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 21, 2015, 07:19:49 AM
ok - i changed the way it works

before, i tried to use a fixed elapse count for QueryPerformanceCounter
i was not prepared to see such low performance counter frequencies

with this one, i use a fixed amount of time, instead

QueryPerformanceFrequency: 00000000_B2D08510h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00340805h
             dwPerfPeriod: 11718789
             dwMultiplier: 256
                 Measured: 11719050, 11719673, 11719275, 11718990, 11718780
                   Sorted: 11718780, 11718990, 11719050, 11719275, 11719673

          GetCpuFrequency: 3000069 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: TWell on October 21, 2015, 07:25:40 AM
AMD E1-6010 1,35 GHz
QueryPerformanceFrequency: 00000000_00141435h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00341E0Dh
             dwPerfPeriod: 5140
             dwMultiplier: 256
                 Measured: 5264337, 5264364, 5264158, 5264324, 5264316
                   Sorted: 5264158, 5264316, 5264324, 5264337, 5264364

          GetCpuFrequency: 1347666 KHz
Title: Re: GetCpuFrequency Tests
Post by: TouEnMasm on October 21, 2015, 08:01:49 AM
QueryPerformanceFrequency: 00000000_003408A8h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 0034080Dh
             dwPerfPeriod: 13321
             dwMultiplier: 256
                 Measured: 13641720, 13641590, 13641614, 13641747, 13641348
                   Sorted: 13641348, 13641590, 13641614, 13641720, 13641747

          GetCpuFrequency: 3492250 KHz

Press any key to continue ...

It is the same frequence given by CPUID

Title: Re: GetCpuFrequency Tests
Post by: sinsi on October 21, 2015, 09:20:54 AM
 :t
QueryPerformanceFrequency: 00000000_003708E5h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00341E0Dh
             dwPerfPeriod: 14089
             dwMultiplier: 256
                 Measured: 14428148, 14428110, 14427783, 14427204, 14428086
                   Sorted: 14427204, 14427783, 14428086, 14428110, 14428148

          GetCpuFrequency: 3693593 KHz
Title: Re: GetCpuFrequency Tests
Post by: MichaelW on October 21, 2015, 10:15:21 AM
Running on my 2.16GHz laptop:

QueryPerformanceFrequency: 00000000_0020492Bh
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 0034080Bh
             dwPerfPeriod: 8265
             dwMultiplier: 256
                 Measured: 8464378, 8464118, 8464456, 8464326, 8464014
                   Sorted: 8464014, 8464118, 8464326, 8464378, 8464456

          GetCpuFrequency: 2166874 KHz

Press any key to continue ...

Title: Re: GetCpuFrequency Tests
Post by: hutch-- on October 21, 2015, 10:20:13 AM
This one works fine on my old i7.


QueryPerformanceFrequency: 00000000_0029B1CAh
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 0034080Bh
             dwPerfPeriod: 10674
             dwMultiplier: 256
                 Measured: 10931202, 10931220, 10931190, 10931190, 10931187
                   Sorted: 10931187, 10931190, 10931190, 10931202, 10931220

          GetCpuFrequency: 2798385 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: Siekmanski on October 21, 2015, 10:31:08 AM
QueryPerformanceFrequency: 00000000_00DA7A64h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 0034080Dh
             dwPerfPeriod: 55930
             dwMultiplier: 256
                 Measured: 13290343, 13289866, 13291558, 13290018, 13289183
                   Sorted: 13289183, 13289866, 13290018, 13290343, 13291558

          GetCpuFrequency: 3402225 KHz

Press any key to continue ...
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 21, 2015, 01:18:38 PM
thanks guys - would like to see Tim's machine(s) to make sure   :P

i see a couple places for improvement in accuracy, but the concept seems to be ok
Title: Re: GetCpuFrequency Tests
Post by: Raistlin on October 21, 2015, 06:19:42 PM
QueryPerformanceFrequency: 00000000_002F9361h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 0034080Dh
             dwPerfPeriod: 12179
             dwMultiplier: 256
                 Measured: 12472264, 12472320, 12472304, 12472120, 12472160
                   Sorted: 12472120, 12472160, 12472264, 12472304, 12472320

          GetCpuFrequency: 3192905 KHz

Press any key to continue ...


Intel Core i5 @ 3.2Ghz
Title: Re: GetCpuFrequency Tests
Post by: TWell on October 21, 2015, 07:00:03 PM
AMD E450 1.65 GHz  :t
QueryPerformanceFrequency: 00000000_0018890Dh
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00341B06h
             dwPerfPeriod: 6281
             dwMultiplier: 256
                 Measured: 6432714, 6432795, 6432741, 6432423, 6432765
                   Sorted: 6432423, 6432714, 6432741, 6432765, 6432795

          GetCpuFrequency: 1646785 KHz
Title: Re: GetCpuFrequency Tests
Post by: dedndave on October 23, 2015, 09:27:29 AM
i updated the attachment at the top of the thread with the final version
it's pretty much like the one you guys just ran, with some accuracy improvements

no need to post results, unless there is some kind of problem   :biggrin:

thanks for all the help   :t
Title: Re: GetCpuFrequency Tests
Post by: Grincheux on December 09, 2015, 11:49:18 PM

QueryPerformanceFrequency: 00000000_00DA7A64h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 00341B05h
             dwPerfPeriod: 55930
             dwMultiplier: 256
                 Measured: 13391013, 13392498, 13392825, 13392039, 13392771
                   Sorted: 13391013, 13392039, 13392498, 13392771, 13392825


          GetCpuFrequency: 3428515 KHz


Press any key to continue ...

Title: Re: GetCpuFrequency Tests
Post by: dedndave on December 11, 2015, 04:32:24 AM
3.4 GHZ, i guess ?
Title: Re: GetCpuFrequency Tests
Post by: guga on December 13, 2015, 10:16:23 PM
Excellent work, dave.

Was it suppose to show only the CPU frequency without other infos ? On your GetCpuFreqStatus3 i have different results then the last one you update. Here are some results on my I7

On the updated app it shows only this:

2933435 KHz

Press any key to continue ...



And on version 3 it shows a more complete  info. :
QueryPerformanceFrequency: 00000000_AED78580h
            EFlags Toggle: 00240000h
                CPUID TSC: Supported
               RDTSC Test: Pass
          GetCpuidSupport: 0034080Bh
             dwPerfPeriod: 11458438
             dwMultiplier: 256
                 Measured: 11458353, 11458341, 11458092, 11458612, 11458678
                   Sorted: 11458092, 11458341, 11458353, 11458612, 11458678

          GetCpuFrequency: 2933337 KHz

Press any key to continue ...



Title: Re: GetCpuFrequency Tests
Post by: dedndave on December 13, 2015, 10:37:28 PM
i was having trouble getting it to work correctly on some machines
so, i had it display additional information   :biggrin:
Title: Re: GetCpuFrequency Tests
Post by: Grincheux on December 19, 2015, 12:41:39 AM
No only 3.0 Ghz
http://www.phrio.biz/download/MyPc.jpg
Title: Re: GetCpuFrequency Tests
Post by: guga on December 19, 2015, 08:11:38 AM
Hi Dave

Can you give me a hand, pls ;)

I´m testing a app i´m using to analyse the different algorithms for timming. In order to the app work, it grabs the Frequency of the CPU. I was using QueryperformanceFrequency to find the proper value, but, in some machines (Intel I5 420 U) the frequency found by your function is different.

For example, using CPUID alone, it displays 1,70 GHZ, but, after computing with GetCpuFrequency the frequency shows 2,39 ?!

That´s from a thread i´m talking here:
http://masm32.com/board/index.php?topic=4925.15

Which values are the correct ones ?
Title: Re: GetCpuFrequency Tests
Post by: dedndave on December 19, 2015, 09:06:38 AM
it may be overclocked - i don't know

here is my final version
there are 2 PROC's: GetCpuFrequency, which requires GetCpuidSupport

        .XCREF
        .NoList
        INCLUDE    \Masm32\Include\Masm32rt.inc
        .686p
        .List

;###############################################################################################

        .DATA

szKernel32  db 'Kernel32.dll',0
szAffinMask db 'SetProcessAffinityMask',0

;###############################################################################################

        .CODE

;***********************************************************************************************

main    PROC

    call    GetCpuFrequency
    print   ustr$(eax),' KHz',13,10,13,10
    inkey
    exit

main    ENDP

;***********************************************************************************************

GetCpuFrequency PROC

;David R. Sheldon (C)opyright 2015
;version 3.01

;EAX = Returns the CPU clock frequency in KHz
;      Returns 0 if any required function is not supported on the current system
;ECX = 1000
;EDX = 0 (ECX and EDX are prepared for DIV ECX, if frequency in MHz is desired)

;---------------------------------

_dwQPFreqHi                 TEXTEQU <Dword Ptr [EBP+20]>
_dwQPFreqLo                 TEXTEQU <Dword Ptr [EBP+16]>
;saved EBX contents                            [EBP+12]
;saved ESI contents                            [EBP+8]
;saved EDI contents                            [EBP+4]
;saved EBP contents                            [EBP]
_hProcess                   TEXTEQU <Dword Ptr [EBP-4]>
_dwPrcsClass                TEXTEQU <Dword Ptr [EBP-8]>
_hThread                    TEXTEQU <Dword Ptr [EBP-12]>
_dwThrdLevel                TEXTEQU <Dword Ptr [EBP-16]>
_dwSystemAffinityMask       TEXTEQU <Dword Ptr [EBP-20]>
_dwProcessAffinityMask      TEXTEQU <Dword Ptr [EBP-24]>
_lpfnSetProcessAffinityMask TEXTEQU <Dword Ptr [EBP-28]>
_dwPerfPeriod               TEXTEQU <Dword Ptr [EBP-32]>
_dwQPCountHi                TEXTEQU <Dword Ptr [EBP-36]>
_dwQPCountLo                TEXTEQU <Dword Ptr [EBP-40]>

;---------------------------------

    push    eax                                         ;[EBP+20] = _dwQPFreqHi
    push    eax                                         ;[EBP+16] = _dwQPFreqLo
    INVOKE  QueryPerformanceFrequency,esp
    .if eax
        push    ebx
        push    esi
        push    edi
        push    ebp
        mov     ebp,esp
        INVOKE  GetCurrentProcess
        push    eax                                     ;[EBP-4]  = _hProcess
        INVOKE  GetPriorityClass,eax
        push    eax                                     ;[EBP-8]  = _dwPrcsClass
        INVOKE  GetCurrentThread
        push    eax                                     ;[EBP-12] = _hThread
        INVOKE  GetThreadPriority,eax
        push    eax                                     ;[EBP-16] = _dwThrdLevel
        INVOKE  GetModuleHandleA,offset szKernel32
        mov     esi,offset szAffinMask
        xchg    eax,ebx                                 ;EBX = hmoduleKernel32
        INVOKE  GetProcAddress,ebx,esi
        mov byte ptr [esi],'G'
        xchg    eax,edi                                 ;EDI = lpfnSetProcessAffinityMask
        INVOKE  GetProcAddress,ebx,esi
        mov byte ptr [esi],'S'
        xor     ecx,ecx
        push    ecx                                     ;[EBP-20] = _dwSystemAffinityMask placeholder
        mov     edx,esp
        push    ecx                                     ;[EBP-24] = _dwProcessAffinityMask placeholder
        .if (eax) && (edi)
            mov     ebx,esp
            push    edi                                 ;[EBP-28] = _lpfnSetProcessAffinityMask
            push    edx                                 ;GetProcessAffinityMask:lpSystemAffinityMask
            push    ebx                                 ;GetProcessAffinityMask:lpProcessAffinityMask
            push    _hProcess                           ;GetProcessAffinityMask:hProcess
            call    eax                                 ;GetProcessAffinityMask
            xor     eax,eax
            mov     edx,_dwProcessAffinityMask
            stc
            .repeat
                rcl     eax,1
                .break .if CARRY?
                test    eax,edx                         ;first available core
            .until !ZERO?
            .if !CARRY?
                push    eax                             ;SetProcessAffinityMask:lpProcessAffinityMask
                push    _hProcess                       ;SetProcessAffinityMask:hProcess
                call    edi                             ;SetProcessAffinityMask
                INVOKE  Sleep,1
            .endif
        .else
            push    ecx                                 ;[EBP-28] = _lpfnSetProcessAffinityMask = NULL
        .endif
        call    GetCpuidSupport
        .if eax&100000h

;calculate performance counter period

            mov     ecx,_dwQPFreqLo
            mov     edx,_dwQPFreqHi
            .if (edx) || (ecx>255)
                shrd    ecx,edx,8
                adc     ecx,0
            .endif
            push    ecx                                 ;[EBP-32] = _dwPerfPeriod

;make 5 measurement passes

            push    eax                                 ;[EBP-36] = _dwQPCountHi placeholder
            push    eax                                 ;[EBP-40] = _dwQPCountLo placeholder
            mov     ebx,5
            mov     edi,esp                             ;EDI = lpqwQPCount
            .repeat
                INVOKE  SetPriorityClass,_hProcess,REALTIME_PRIORITY_CLASS
                INVOKE  Sleep,1
                INVOKE  SetThreadPriority,_hThread,THREAD_PRIORITY_TIME_CRITICAL
                INVOKE  Sleep,1
                INVOKE  QueryPerformanceCounter,edi
                mov     esi,[edi]
                .repeat
                    INVOKE  QueryPerformanceCounter,edi
                .until esi!=[edi]
                rdtsc
                mov     esi,[edi]
                push    eax
                .repeat
                    INVOKE  QueryPerformanceCounter,edi
                    mov     eax,[edi]
                    sub     eax,esi
                .until eax>=_dwPerfPeriod
                pop     ecx
                rdtsc
                sub     eax,ecx
                push    eax                             ;store measurement on stack
                INVOKE  SetPriorityClass,_hProcess,_dwPrcsClass
                INVOKE  Sleep,1
                INVOKE  SetThreadPriority,_hThread,_dwThrdLevel
                INVOKE  Sleep,1
                dec     ebx
            .until ZERO?

;recall the 5 measurements from the stack and in-register sort

            pop     esi
            pop     edx
            pop     eax
            pop     ecx
            pop     ebx
            .if ebx>ecx
                xchg    ebx,ecx
            .endif
            .if ecx>eax
                xchg    eax,ecx
            .endif
            .if eax>edx
                xchg    eax,edx
            .endif
            .if edx>esi
                xchg    edx,esi
            .endif
            .if edx<eax
                xchg    eax,edx
            .endif
            .if eax<ecx
                xchg    eax,ecx
            .endif
            .if ecx<ebx
                xchg    ebx,ecx
            .endif
            .if ecx>eax
                xchg    eax,ecx
            .endif
            .if eax>edx
                xchg    eax,edx
            .endif
            .if eax<ecx
                xchg    eax,ecx
            .endif

;ESI = A(4) highest
;EDX = A(3)
;EAX = A(2)
;ECX = A(1)
;EBX = A(0) lowest

;throw away the lowest and highest, A(0) and A(4)
;find the closest pair of A(1),A(2) or A(2),A(3)
;  if A(3)-A(2) > A(2)-A(1), use (A(2)+A(1))/2 as the result
;  if A(3)-A(2) < A(2)-A(1), use (A(3)+A(2))/2 as the result
;  if A(3)-A(2) = A(2)-A(1), use A(2) as the result

            mov     esi,edx                             ;ESI = A(3)
            mov     ebx,eax                             ;EBX = A(2)
            sub     esi,eax                             ;ESI = A(3)-A(2)
            sub     ebx,ecx                             ;EBX = A(2)-A(1)
            cmp     ebx,esi
            .if CARRY?
                add     eax,ecx
            .elseif !ZERO?
                add     eax,edx
            .else
                shl     eax,1
            .endif
            shr     eax,1
            adc     eax,0

;scale the result, Freq(KHz) = Measurement*qwQPCount/1000*dwPerfPeriod

            mov     esi,eax
            xor     edi,edi
            mul     _dwQPFreqLo
            xchg    eax,esi
            xchg    edx,edi
            mul     _dwQPFreqHi
            mov     ecx,_dwPerfPeriod
            add     eax,edi                             ;product in EAX:ESI
            div     ecx
            xchg    eax,esi
            div     ecx                                 ;quotient in ESI:EAX, modulo in EDX
            mov     edx,esi
            mov     ecx,1000
            div     ecx
            shr     ecx,1
            cmp     edx,ecx
            sbb     eax,-1
        .else
            xor     eax,eax
        .endif

;restore affinity and exit

        mov     ecx,_lpfnSetProcessAffinityMask
        .if ecx
            push    eax
            push    _dwProcessAffinityMask              ;SetProcessAffinityMask:dwProcessAffinityMask
            push    _hProcess                           ;SetProcessAffinityMask:hProcess
            call    ecx                                 ;SetProcessAffinityMask
            INVOKE  Sleep,0
            pop     eax
        .endif
        mov     ecx,1000
        xor     edx,edx
        leave
        pop     edi
        pop     esi
        pop     ebx
    .endif
    add     esp,8
    ret

GetCpuFrequency ENDP

;***********************************************************************************************

GetCpuidSupport PROC

;David R. Sheldon (C)opyright 2015
;version 3.01

;Returns a value in EAX with the following flag bits:
;
; Bit            Description
;
;0-7             Highest CPUID standard leaf supported
;8-15            Highest CPUID extended leaf supported
; 18             Processor is 80486 or later
; 20             Processor has TimeStampCounter (RDTSC supported)
; 21             Processor supports CPUID instruction
;
;All other bits are reserved.
;It is possible, however unlikely, that different values may be returned from individual cores.
;It is advisable to select a single specific core prior to calling this routine.

;---------------------------------

    push    ebx
    pushfd
    mov     ecx,240000h                                 ;bit 21 = CPUID, bit 18 = 486+
    pop     ebx
    mov     edx,ebx                                     ;EDX = original EFlags
    xor     ebx,ecx                                     ;EBX = toggled EFlags
    push    ebx
    popfd                                               ;EFlags = toggled flags
    pushfd
    pop     ebx                                         ;EBX = test flags
    push    edx                                         ;original EFlags on stack
    xor     ebx,edx                                     ;EBX = toggle result
    and     ebx,ecx
    mov     ecx,200000h                                 ;ECX = bit 21 only
    xor     eax,eax                                     ;EAX = CPUID leaf 0
    test    ebx,ecx
    .if !ZERO?
        or      edx,ecx
        push    ebx
        push    edx
        popfd
        cpuid
        pop     ebx
        .if ah==5
            or     ebx,100000h                          ;TSC supported for pre-b0 stepping
        .elseif eax
            .if eax>0FFh
                mov     bl,0FFh
            .else
                mov     bl,al
            .endif
            mov     eax,1
            push    ebx
            cpuid
            pop     ebx
            and     edx,10h                             ;TSC support flag
            shl     edx,16
            or      ebx,edx
            mov     eax,80000000h
            push    ebx
            cpuid
            pop     ebx
            .if eax>800000FFh
                mov     bh,0FFh
            .else
                mov     bh,al
            .endif
        .endif
        .if ebx&100000h
            rdtsc
            push    eax
            INVOKE  Sleep,1
            rdtsc
            pop     edx
            .if eax==edx
                and     ebx,0FFEFFFFFh                  ;TSC not running
            .endif
        .endif
    .endif
    xchg    eax,ebx
    popfd                                               ;EFlags = original
    pop     ebx
    ret

GetCpuidSupport ENDP

;###############################################################################################

        END     main
Title: Re: GetCpuFrequency Tests
Post by: dedndave on December 19, 2015, 09:08:15 AM
2.39 GHz ~ 2.4 GHz, which is a common clock freq
Title: Re: GetCpuFrequency Tests
Post by: dedndave on December 19, 2015, 09:12:46 AM
http://www.notebookcheck.net/Intel-Core-i5-4210U-Notebook-Processor.115081.0.html (http://www.notebookcheck.net/Intel-Core-i5-4210U-Notebook-Processor.115081.0.html)

QuoteEach core offers a base speed of 1.7 GHz, but can dynamically increase clock rates
with Turbo Boost up to 2.7 GHz for 1 active core or 2.4 GHz for 2 active cores.
Title: Re: GetCpuFrequency Tests
Post by: mabdelouahab on December 19, 2015, 09:26:11 AM
http://masm32.com/board/index.php?topic=4925.msg53020#msg53020
Title: Re: GetCpuFrequency Tests
Post by: guga on December 19, 2015, 10:06:04 AM
Thanks Dave. A LOT ! Your function is amazing. I´m using it on the app i was talking about   I hope that once i succeed to finish the fine tunnings, i can make a dll so you guys can use it on your apps too. Biased on the results the guys are reporting, the values seems accurated :)

I found 2 problems only. The huge variance found in mabdelouahab (which maybe explained by the increasing of speed as you told) and the problems when analyzing short codes (as "xor eax eax" alone) . On both, although the values of the mean are acceptable, the variance is too high to be correct, meaning that something has passed through a function i built to block such rare situations.
Title: Re: GetCpuFrequency Tests
Post by: guga on December 24, 2015, 05:41:48 AM
Hi Dave,

does your function works inside a dll? I mean, since it is using SetProcessAffinityMask Api, can the function be used inside a dll (As an export function or not) ?

https://msdn.microsoft.com/pt-br/library/windows/desktop/ms686223%28v=vs.85%29.aspx
Title: Re: GetCpuFrequency Tests
Post by: dedndave on December 24, 2015, 06:04:13 AM
what they mean is....
don't use it in a DLL that may be used by more than one process at a time
Title: Re: GetCpuFrequency Tests
Post by: dedndave on December 24, 2015, 06:07:29 AM
...my intention is to use it in a static library (LIB)
the code is then imported to the EXE when you build it
Title: Re: GetCpuFrequency Tests
Post by: guga on December 24, 2015, 06:23:17 AM
Phew ! (http://i65.tinypic.com/10rl407.png)

I thought for a moment i´ll have to rewrite the Benchmark app to it allow the dll form :greensml:

I was confused by the msdn doc.
Title: Re: GetCpuFrequency Tests
Post by: TWell on December 24, 2015, 06:42:15 AM
If you use GetCurrentProcess(), it is calling process handle?
Title: Re: GetCpuFrequency Tests
Post by: guga on December 25, 2015, 01:36:33 AM
Hi dave, take a look at this source

http://fluid-particles.googlecode.com/svn/trunk/CoreDetection/CpuTopology.cpp

You may find interesting the cpu classes :)

Btw....Also the project per se is quite amazing (Fluid particles system)
Title: Re: GetCpuFrequency Tests
Post by: guga on December 26, 2015, 03:05:58 AM
Dave, do not use SetProcessAffinityMask !!!

I found a bug (at least on WinP) inside that API. The stack is being returned incorrectly. There is a major stack problem there. There is a lack of "leave"  or "mov esp ebp". This is causing the function to needs an adjustment on the stack after it is used. I made some tests on your function and saved the registers while using it. All i left was eax to it returns the proper Flags retrieved by GetCpuidSupport. The problem was after using the GetCpuFrequency it was saving at ebx the same value as in eax (ebx was being "poped" by eax), regardless i saved all registers with the chain of push/pop, during the entrance and exiting of the function. Take a look at the disassembled code from kernel32.dll as below:


; BOOL __stdcall SetProcessAffinityMask(HANDLE hProcess, DWORD_PTR dwProcessAffinityMask)
public _SetProcessAffinityMask@8
_SetProcessAffinityMask@8 proc near ; DATA XREF: .text:off_7C802654o

hProcess = dword ptr  8
dwProcessAffinityMask= dword ptr  0Ch

mov edi, edi
push ebp
mov ebp, esp
push 4
lea eax, [ebp+dwProcessAffinityMask]
push eax
push 21
push [ebp+hProcess]
call ds:__imp__NtSetInformationProcess@16 ; NtSetInformationProcess(x,x,x,x)
test eax, eax
jge short loc_7C862E48
push eax
call _BaseSetLastNTError@4 ; BaseSetLastNTError(x)
xor eax, eax
jmp short loc_7C862E4B
; ---------------------------------------------------------------------------

loc_7C862E48:
xor eax, eax
inc eax

loc_7C862E4B: ; MISSING A "LEAVE" OR "MOV ESP EBB" HERE !!!!
pop ebp
retn 8
_SetProcessAffinityMask@8 endp


I succeeded to fix that and rebuilt both APis used:GetProcessAffinityMask and SetProcessAffinityMask. I´ll post the corrected functions on another thread. I managed to fix retrieving the values from the TEB/PEB structures as the same way the original APis did, but, i fixed them, while on XP it is still broken ! (I believe that probably, it is also broken in others windows versions as well, but i didn´t analyzed them yet)
Title: Re: GetCpuFrequency Tests
Post by: nidud on December 26, 2015, 03:25:08 AM
deleted
Title: Re: GetCpuFrequency Tests
Post by: jj2007 on December 26, 2015, 03:39:56 AM
Quote from: guga on December 26, 2015, 03:05:58 AMI found a bug (at least on WinP) inside that API. The stack is being returned incorrectly. There is a major stack problem there. There is a lack of "leave"  or "mov esp ebp". This is causing the function to needs an adjustment on the stack after it is used.

Can you post an executable that shows this behaviour, with an int 3 inserted shortly before?
My tests on Win XP and Win7-64 do not show any abnormal behaviour:

include \masm32\MasmBasic\MasmBasic.inc      ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  mov esi, 111111111
  mov edi, 222222222
  mov ebx, 333333333
  mov ecx, 444444444
  deb 4, "In", esi, edi, ebx, ebp, ecx, esp
  ClearLastError
  push ecx
  invoke SetProcessAffinityMask, rv(GetCurrentProcess), 1
  pop ecx
  deb 4, "SPAM", eax, $Err$()
  deb 4, "Out", esi, edi, ebx, ebp, ecx, esp
EndOfCode


In
esi             111111111
edi             222222222
ebx             333333333
ebp             1638292
ecx             444444444
esp             1638284

SPAM
eax             1
$Err$()         Operazione completata.


Out
esi             111111111
edi             222222222
ebx             333333333
ebp             1638292
ecx             444444444
esp             1638284
Title: Re: GetCpuFrequency Tests
Post by: guga on December 26, 2015, 05:23:19 AM
Hi Guys...Many tks for the feedback.

Indeed that was not a fault of GetProcessAffinityMask/SetProcessAffinityMask.

The problem was in one of my macros. The counting of the stack was incorrect, leading the values to return 4 bytes ahead

many tks, and Merry Xmas, to you all :)
Title: Re: GetCpuFrequency Tests
Post by: guga on December 26, 2015, 05:57:11 AM
In any case, if someone wants a new version of those Apis (GetProcessAffinityMask and SetProcessAffinityMask) here they are:

GetProcessAffinityMask

[BASE_STATIC_SERVER_DATA.WindowsDirectory.LengthDis 0
BASE_STATIC_SERVER_DATA.WindowsDirectory.MaximumLengthDis 2
BASE_STATIC_SERVER_DATA.WindowsDirectory.BufferDis 4
BASE_STATIC_SERVER_DATA.WindowsSystemDirectory.LengthDis 8
BASE_STATIC_SERVER_DATA.WindowsSystemDirectory.MaximumLengthDis 10
BASE_STATIC_SERVER_DATA.WindowsSystemDirectory.BufferDis 12
BASE_STATIC_SERVER_DATA.NamedObjectDirectory.LengthDis 16
BASE_STATIC_SERVER_DATA.NamedObjectDirectory.MaximumLengthDis 18
BASE_STATIC_SERVER_DATA.NamedObjectDirectory.BufferDis 20
BASE_STATIC_SERVER_DATA.WindowsMajorVersionDis 24
BASE_STATIC_SERVER_DATA.WindowsMinorVersionDis 26
BASE_STATIC_SERVER_DATA.BuildNumberDis 28
BASE_STATIC_SERVER_DATA.CSD.wServicePackMajorDis 30
BASE_STATIC_SERVER_DATA.CSD.wServicePackMinorDis 32
BASE_STATIC_SERVER_DATA.CSD.szCSDVersionDis 34
BASE_STATIC_SERVER_DATA.Padding1Dis 286
BASE_STATIC_SERVER_DATA.SysInfo.ReservedDis 288
BASE_STATIC_SERVER_DATA.SysInfo.TimerResolutionDis 292
BASE_STATIC_SERVER_DATA.SysInfo.PageSizeDis 296
BASE_STATIC_SERVER_DATA.SysInfo.NumberOfPhysicalPagesDis 300
BASE_STATIC_SERVER_DATA.SysInfo.LowestPhysicalPageNumberDis 304
BASE_STATIC_SERVER_DATA.SysInfo.HighestPhysicalPageNumberDis 308
BASE_STATIC_SERVER_DATA.SysInfo.AllocationGranularityDis 312
BASE_STATIC_SERVER_DATA.SysInfo.MinimumUserModeAddressDis 316
BASE_STATIC_SERVER_DATA.SysInfo.MaximumUserModeAddressDis 320
BASE_STATIC_SERVER_DATA.SysInfo.ActiveProcessorsAffinityMaskDis 324
BASE_STATIC_SERVER_DATA.SysInfo.NumberOfProcessorsDis 328
BASE_STATIC_SERVER_DATA.SysInfo.Padding1Dis 329
BASE_STATIC_SERVER_DATA.Padding2Dis 332
BASE_STATIC_SERVER_DATA.TimeOfDay.BootTimeDis 336
BASE_STATIC_SERVER_DATA.TimeOfDay.CurrentTimeDis 344
BASE_STATIC_SERVER_DATA.TimeOfDay.TimeZoneBiasDis 352
BASE_STATIC_SERVER_DATA.TimeOfDay.TimeZoneIdDis 360
BASE_STATIC_SERVER_DATA.TimeOfDay.ReservedDis 364
BASE_STATIC_SERVER_DATA.IniFileMappingDis 368
BASE_STATIC_SERVER_DATA.NlsUserInfo.sAbbrevLangNameDis 372
BASE_STATIC_SERVER_DATA.NlsUserInfo.iCountryDis 532
BASE_STATIC_SERVER_DATA.NlsUserInfo.sCountryDis 692
BASE_STATIC_SERVER_DATA.NlsUserInfo.sListDis 852
BASE_STATIC_SERVER_DATA.NlsUserInfo.iMeasureDis 1012
BASE_STATIC_SERVER_DATA.NlsUserInfo.sDecimalDis 1172
BASE_STATIC_SERVER_DATA.NlsUserInfo.sThousandDis 1332
BASE_STATIC_SERVER_DATA.NlsUserInfo.sGroupingDis 1492
BASE_STATIC_SERVER_DATA.NlsUserInfo.iDigitsDis 1652
BASE_STATIC_SERVER_DATA.NlsUserInfo.iLZeroDis 1812
BASE_STATIC_SERVER_DATA.NlsUserInfo.iNegNumberDis 1972
BASE_STATIC_SERVER_DATA.NlsUserInfo.sCurrencyDis 2132
BASE_STATIC_SERVER_DATA.NlsUserInfo.sMonDecSepDis 2292
BASE_STATIC_SERVER_DATA.NlsUserInfo.sMonThouSepDis 2452
BASE_STATIC_SERVER_DATA.NlsUserInfo.sMonGroupingDis 2612
BASE_STATIC_SERVER_DATA.NlsUserInfo.iCurrDigitsDis 2772
BASE_STATIC_SERVER_DATA.NlsUserInfo.iCurrencyDis 2932
BASE_STATIC_SERVER_DATA.NlsUserInfo.iNegCurrDis 3092
BASE_STATIC_SERVER_DATA.NlsUserInfo.sPosSignDis 3252
BASE_STATIC_SERVER_DATA.NlsUserInfo.sNegSignDis 3412
BASE_STATIC_SERVER_DATA.NlsUserInfo.sTimeFormatDis 3572
BASE_STATIC_SERVER_DATA.NlsUserInfo.sTimeDis 3732
BASE_STATIC_SERVER_DATA.NlsUserInfo.iTimeDis 3892
BASE_STATIC_SERVER_DATA.NlsUserInfo.iTLZeroDis 4052
BASE_STATIC_SERVER_DATA.NlsUserInfo.iTimeMarkPosnDis 4212
BASE_STATIC_SERVER_DATA.NlsUserInfo.s1159Dis 4372
BASE_STATIC_SERVER_DATA.NlsUserInfo.s2359Dis 4532
BASE_STATIC_SERVER_DATA.NlsUserInfo.sShortDateDis 4692
BASE_STATIC_SERVER_DATA.NlsUserInfo.sDateDis 4852
BASE_STATIC_SERVER_DATA.NlsUserInfo.iDateDis 5012
BASE_STATIC_SERVER_DATA.NlsUserInfo.sLongDateDis 5172
BASE_STATIC_SERVER_DATA.NlsUserInfo.iCalTypeDis 5332
BASE_STATIC_SERVER_DATA.NlsUserInfo.iFirstDayDis 5492
BASE_STATIC_SERVER_DATA.NlsUserInfo.iFirstWeekDis 5652
BASE_STATIC_SERVER_DATA.NlsUserInfo.sLocaleDis 5812
BASE_STATIC_SERVER_DATA.NlsUserInfo.UserLocaleIdDis 5972
BASE_STATIC_SERVER_DATA.NlsUserInfo.fCacheValidDis 5976
BASE_STATIC_SERVER_DATA.DefaultSeparateVDMDis 5980
BASE_STATIC_SERVER_DATA.Wx86EnabledDis 5981
BASE_STATIC_SERVER_DATA.Padding3Dis 5982]

[Size_Of_BASE_STATIC_SERVER_DATA 5984]


[PROCESS_BASIC_INFORMATION.ExitStatusDis 0
PROCESS_BASIC_INFORMATION.PebBaseAddressDis 4
PROCESS_BASIC_INFORMATION.AffinityMaskDis 8
PROCESS_BASIC_INFORMATION.BasePriorityDis 12
PROCESS_BASIC_INFORMATION.UniqueProcessIdDis 16
PROCESS_BASIC_INFORMATION.InheritedFromUniqueProcessIdDis 20]

[Size_of_PROCESS_BASIC_INFORMATION 24]

[BaseStaticServerData: D$ 0]

Proc GetProcessAffinityMask:
    Arguments @hProcess, @lpProcessAffinityMask, @lpSystemAffinityMask
    Structure @PROCESS_BASIC_INFORMATION 24, @PROCESS_BASIC_INFORMATION.ExitStatusDis 0,
              @PROCESS_BASIC_INFORMATION.PebBaseAddressDis 4, @PROCESS_BASIC_INFORMATION.AffinityMaskDis 8,
              @PROCESS_BASIC_INFORMATION.BasePriorityDis 12, @PROCESS_BASIC_INFORMATION.UniqueProcessIdDis 16,
              @PROCESS_BASIC_INFORMATION.InheritedFromUniqueProcessIdDis 20
    Uses ecx, edx

    call 'Ntdll.NtQueryInformationProcess' D@hProcess, &PROCESS_BASICINFORMATION,
                                           D@PROCESS_BASIC_INFORMATION, Size_of_PROCESS_BASIC_INFORMATION, 0
    If eax <> &STATUS_SUCCESS
        call BaseSetLastNTError eax
        xor eax eax
    Else
       
        ; Copy the affinity mask, and get the system one from our shared data
        mov ecx D@lpProcessAffinityMask
        mov eax D@PROCESS_BASIC_INFORMATION.AffinityMaskDis | mov D$ecx eax

        call 'ntdll.RtlAcquirePebLock' ; <------- Always lock the PEb before using it.
        call GetBaseStaticServerFromTEB BaseStaticServerData
        mov eax D$BaseStaticServerData
        mov eax D$eax+BASE_STATIC_SERVER_DATA.SysInfo.NumberOfProcessorsDis
        mov ecx D@lpSystemAffinityMask | mov D$ecx eax
        call 'ntdll.RtlReleasePebLock'; <---- And, of course, don´t forget to unlock it.
        mov eax &TRUE
    End_If

EndP


SetProcessAffinityMask

Proc SetProcessAffinityMask:
    Arguments @hProcess, @dwProcessAffinityMask
    Uses ecx, edx

    ; Directly set the affinity mask
    lea eax D@dwProcessAffinityMask
    call 'Ntdll.NtSetInformationProcess' D@hProcess, &PROCESS_AFFINITYMASK, eax, 4

    If eax <> &STATUS_SUCCESS
        call BaseSetLastNTError eax
        xor eax eax
    Else
        mov eax &TRUE
    End_If

EndP


And the additional functions

BaseSetLastNTError

Proc BaseSetLastNTError:
    Arguments @ErrorCode
    Uses esi, ecx, edx, ebx

    call 'ntdll.RtlNtStatusToDosError' D@ErrorCode | mov esi eax
    call 'kernel32.SetLastError' eax
    mov eax esi

EndP


GetBaseStaticServerFromTEB


;;
         GetBaseStaticServerFromTEB

            This function retrieves the pointer to a BASE_STATIC_SERVER_DATA structure that contains information about your system.

         Arguments:
           pOutput (out): Pointer to a Variable that will holds the data to the structure BASE_STATIC_SERVER_DATA

        Returned Values:
               This function will return a pointer to BASE_STATIC_SERVER_DATA structure. Also, it will store it on the proper variable at pOutput

       Example of usage:

          [BaseStaticServerData: D$ 0]
                    call 'ntdll.RtlAcquirePebLock' ; <------- Always lock the PEb before using it.
                    call GetBaseStaticServerFromTEB BaseStaticServerData
                    add eax BASE_STATIC_SERVER_DATA.NamedObjectDirectory.LengthDis
                     (...)
                    call 'ntdll.RtlReleasePebLock' <---- And, of course, don´t forget to unlock it.

       See Also: BASE_STATIC_SERVER_DATA structure

        Remarks: Always lock and unlock the PEb when retrieving the information from TEB/PEB data.
                        To lock you must use a call to  'ntdll.RtlAcquirePebLock' and to unlock you must use the function ntdll.RtlReleasePebLock
                         See the example above.

      Author:
         Gustavo Trigueiros (aka: Beyond2000! or Guga)
         jul/2014
;;


[TEB.Tib.ExceptionListDis 0
TEB.Tib.StackBaseDis 4
TEB.Tib.StackLimitDis 8
TEB.Tib.SubSystemTibDis 12
TEB.Tib.FiberDataDis 16
TEB.VersionDis 16
TEB.Tib.ArbitraryUserPointerDis 20
TEB.Tib.SelfDis 24
TEB.EnvironmentPointerDis 28
TEB.ClientId.UniqueProcessDis 32
TEB.ClientId.UniqueThreadDis 36
TEB.ActiveRpcDDis 40
TEB.ThreadLocalStoragePointerDis 44
TEB.PebDis 48
TEB.LastErrorValueDis 52
TEB.CountOfOwnedCriticalSectionsDis 56
TEB.CsrClientThreadDis 60
TEB.Win32ThreadInfoDis 64
TEB.Win32ClientInfoDis 68
TEB.WOW32ReservedDis 192
TEB.CurrentLocaleDis 196
TEB.FpSoftwareStatusRegisterDis 200
TEB.SystemReserved1Dis 204
TEB.Spare1Dis 420
TEB.ExceptionCodeDis 424
TEB.SpareBs1Dis 428
TEB.SystemReserved2Dis 468
TEB.GdiTebBatch.OffsetDis 508
TEB.GdiTebBatch.HDCDis 512
TEB.GdiTebBatch.BufferDis 516
TEB.gdiRgnDis 1756
TEB.gdiPenDis 1760
TEB.gdiBrushDis 1764
TEB.RealClientId.UniqueProcessDis 1768
TEB.RealClientId.UniqueThreadDis 1772
TEB.GdiCachedProcessDDis 1776
TEB.GdiClientPIDDis 1780
TEB.GdiClientTIDDis 1784
TEB.GdiThreadLocaleInfoDis 1788
TEB.UserReservedDis 1792
TEB.glDispachTableDis 1812
TEB.glReserved1Dis 2932
TEB.glReserved2Dis 3036
TEB.glSectionInfoDis 3040
TEB.glSectionDis 3044
TEB.glTableDis 3048
TEB.glCurrentRCDis 3052
TEB.glContextDis 3056
TEB.LastStatusValueDis 3060
TEB.StaticUnicodeString.LengthDis 3064
TEB.StaticUnicodeString.MaximumLengthDis 3066
TEB.StaticUnicodeString.BufferDis 3068
TEB.StaticUnicodeBufferDis 3072
TEB.PADDINGDis 3594
TEB.DeallocationStackDis 3596
TEB.TlsSlotsDis 3600
TEB.TlsLinks.FlinkDis 3856
TEB.TlsLinks.BlinkDis 3860
TEB.VdmDis 3864
TEB.ReservedForNtRpcDis 3868
TEB.DbgSsReservedDis 3872
TEB.HardErrorDisabledDis 3880
TEB.InstrumentationDis 3884
TEB.WinSockDataDis 3948
TEB.GdiBatchCountDis 3952
TEB.Spare2Dis 3956
TEB.Spare3Dis 3960
TEB.Spare4Dis 3964
TEB.ReservedForOleDis 3968
TEB.WaitingOnLoaderLockDis 3972
TEB.Reserved5Dis 3976
TEB.TlsExpansionSlotsDis 3988]

[PEB.InheritedAddressSpaceDis 0
PEB.ReadImageFileExecOptionsDis 1
PEB.BeingDebuggedDis 2
PEB.SpareBoolDis 3
PEB.MutantDis 4
PEB.ImageBaseAddressDis 8
PEB.LdrDataDis 12
PEB.ProcessParametersDis 16
PEB.SubSystemDataDis 20
PEB.ProcessHeapDis 24
PEB.FastPebLockDis 28
PEB.FastPebLockRoutineDis 32
PEB.FastPebUnlockRoutineDis 36
PEB.EnvironmentUpdateCountDis 40
PEB.KernelCallbackTableDis 44
PEB.EventLogSectionDis 48
PEB.EventLogDis 52
PEB.FreeListDis 56
PEB.TlsExpansionCounterDis 60
PEB.TlsBitmapDis 64
PEB.TlsBitmapBitsDis 68
PEB.ReadOnlySharedMemoryBaseDis 76
PEB.ReadOnlySharedMemoryHeapDis 80
PEB.ReadOnlyStaticServerDataDis 84
PEB.AnsiCodePageDataDis 88
PEB.OemCodePageDataDis 92
PEB.UnicodeCaseTableDataDis 96
PEB.NumberOfProcessorsDis 100
PEB.NtGlobalFlagDis 104
PEB.Spare2Dis 108
PEB.CriticalSectionTimeoutDis 112
PEB.HeapSegmentReserveDis 120
PEB.HeapSegmentCommitDis 124
PEB.HeapDeCommitTotalFreeThresholdDis 128
PEB.HeapDeCommitFreeBlockThresholdDis 132
PEB.NumberOfHeapsDis 136
PEB.MaximumNumberOfHeapsDis 140
PEB.ProcessHeapsDis 144
PEB.GdiSharedHandleTableDis 148
PEB.ProcessStarterHelperDis 152
PEB.GdiDCAttributeListDis 156
PEB.LoaderLockDis 160
PEB.OSMajorVersionDis 164
PEB.OSMinorVersionDis 168
PEB.OSBuildNumberDis 172
PEB.OSPlatformIdDis 176
PEB.ImageSubSystemDis 180
PEB.ImageSubSystemMajorVersionDis 184
PEB.ImageSubSystemMinorVersionDis 188
PEB.ImageProcessAffinityMaskDis 192
PEB.GdiDBufferDis 196
PEB.PostProcessInitRoutineDis 332
PEB.TlsExpansionBitmapDis 336
PEB.TlsExpansionBitmapBitsDis 340
PEB.SessionIdDis 468]

[TEXT_INFO.ReservedDis 0
TEXT_INFO.SystemStringsDis 4]

[Size_Of_TEXT_INFO 8]

Proc GetBaseStaticServerFromTEB:
    Arguments @pOutput
    Uses edi

    mov edi D@pOutput
    mov eax D$fs:TEB.Tib.SelfDis ; retrieve TEB structure for the current process
    mov eax D$eax+TEB.PebDis ; pointer to a PEB structure
    mov eax D$eax+PEB.ReadOnlyStaticServerDataDis ; retrieve the ReadOnlyStaticServerData (a TEXT_INFO structure)
    mov eax D$eax+TEXT_INFO.SystemStringsDis ; pointer to a BASE_STATIC_SERVER_DATA structure and not a SYSTEM_STRINGS structure (eah member points to a UNICODE_STRING String)
    mov D$edi eax

EndP


Equates :
PROCESS_BASICINFORMATION = 0
PROCESS_AFFINITYMASK = 21
STATUS_SUCCESS = 0

or, another version of GetProcessAffinityMask
Alternative version

Proc GetProcessAffinityMask:
    Arguments @hProcess, @lpProcessAffinityMask, @lpSystemAffinityMask
    Structure @PROCESS_BASIC_INFORMATION 24, @PROCESS_BASIC_INFORMATION.ExitStatusDis 0,
              @PROCESS_BASIC_INFORMATION.PebBaseAddressDis 4, @PROCESS_BASIC_INFORMATION.AffinityMaskDis 8,
              @PROCESS_BASIC_INFORMATION.BasePriorityDis 12, @PROCESS_BASIC_INFORMATION.UniqueProcessIdDis 16,
              @PROCESS_BASIC_INFORMATION.InheritedFromUniqueProcessIdDis 20
    Uses ecx, edx

    call 'Ntdll.NtQueryInformationProcess' D@hProcess, &PROCESS_BASICINFORMATION,
                                           D@PROCESS_BASIC_INFORMATION, Size_of_PROCESS_BASIC_INFORMATION, 0
    If eax <> &STATUS_SUCCESS
        call BaseSetLastNTError eax
        xor eax eax
    Else
       
        ; Copy the affinity mask, and get the system one from our shared data
        mov ecx D@lpProcessAffinityMask
        mov eax D@PROCESS_BASIC_INFORMATION.AffinityMaskDis | mov D$ecx eax

        mov ecx D@lpSystemAffinityMask
        mov eax D@PROCESS_BASIC_INFORMATION.PebBaseAddressDis | mov eax D$eax+PEB.ReadOnlyStaticServerDataDis
        mov eax D$eax+TEXT_INFO.SystemStringsDis | mov eax D$eax+BASE_STATIC_SERVER_DATA.SysInfo.NumberOfProcessorsDis
        mov D$ecx eax
        mov eax &TRUE
    End_If

EndP