Author Topic: Help with QueryPerformanceCounter and 64 bit numbers  (Read 2569 times)

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5900
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #30 on: April 12, 2018, 08:54:01 PM »
The API is simple to use.


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    include \masm32\include\masm32rt.inc
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

comment * -----------------------------------------------------
                        Build this  template with
                       "CONSOLE ASSEMBLE AND LINK"
        ----------------------------------------------------- *

    .code

start:
   
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    call main
    inkey
    exit

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

main proc

    LOCAL var1  :DWORD

    push esi
    push edi

    lea esi, var1                           ; load the address
    mov edi, 100                            ; set the counter

  @@:
    invoke QueryPerformanceCounter, esi     ; call the API
    print str$([esi]),13,10                 ; display low DWORD
    sub edi, 1                              ; decrement counter
    jnz @B                                  ; loop again if not 0

    pop edi
    pop esi

    ret

main endp


; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

end start
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

Siekmanski

  • Member
  • *****
  • Posts: 1684
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #31 on: April 12, 2018, 08:58:16 PM »
var1 should be QWORD size
Creative coders use backward thinking techniques as a strategy.

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #32 on: April 12, 2018, 09:32:53 PM »
QueryPerformanceCounter() is defined in winbase.h

;BOOL
QueryPerformanceCounter proto WINAPI \
    lpPerformanceCount: PTR LARGE_INTEGER

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 5900
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #33 on: April 12, 2018, 09:56:57 PM »
You are right, it should be in 32 bit,

    LOCAL var1  :DWORD
    LOCAL dumm  :DWORD

I added it later.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :biggrin:

nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #34 on: April 12, 2018, 10:21:51 PM »

    LOCAL dumm  :DWORD
    LOCAL var1  :DWORD

or maybe like this:

    LOCAL var1[2]  :DWORD


dedndave

  • Member
  • *****
  • Posts: 8808
  • Still using Abacus 2.0
    • DednDave
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #35 on: April 13, 2018, 01:52:43 AM »
you might use the LARGE_INTEGER structure, as defined in windows.inc

Code: [Select]
LARGE_INTEGER UNION
    STRUCT
      LowPart  DWORD ?
      HighPart DWORD ?
    ENDS
  QuadPart QWORD ?
LARGE_INTEGER ENDS

handy, because you can access the values as either 2 DWORDs or 1 QWORD

Code: [Select]
    LOCAL  liPerfCtr   :LARGE_INTEGER

LordAdef

  • Member
  • ****
  • Posts: 604
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #36 on: April 13, 2018, 02:04:17 AM »
Wait,
what Hutch was first doing is what I am doing, simply passing the first dword straight away is already what we want. we don't need any extra work unless we want the full qword.


Or I am missing something?




nidud

  • Member
  • *****
  • Posts: 1614
    • https://github.com/nidud/asmc
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #37 on: April 13, 2018, 02:17:46 AM »
var1 is at [ebp-4] so the result overwrite the next dword and thus trash whatever is there. In this case that will be the pushed value of ebp which most likely will be set to zero on return.

LordAdef

  • Member
  • ****
  • Posts: 604
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #38 on: April 13, 2018, 02:28:09 AM »
But I mean,

queryperformancecounter, addr temp
mov eax, temp

that's the dword we need, right? The low dword is the first data in the union, so this should suffice

jj2007

  • Member
  • *****
  • Posts: 8845
  • Assembler is fun ;-)
    • MasmBasic
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #39 on: April 13, 2018, 02:34:39 AM »
Most of the time the DWORD is enough; occasionally, you'll get overflow, though.

But what's wrong with the complete solution that I posted in reply #4? Plain Masm32 8)

Btw if you need milliseconds instead of seconds, just insert a line as shown below, and adjust the unit:
Code: [Select]
include \masm32\include\masm32rt.inc

.data?
timeStart dq ?
timeEnd dq ?
timeFrequency dq ?
timeElapsed dq ?

.code
start:
  invoke QueryPerformanceFrequency, addr timeFrequency
  invoke QueryPerformanceCounter, addr timeStart
  invoke Sleep, 300
  invoke QueryPerformanceCounter, addr timeEnd
  fild timeEnd
  fild timeStart
  fsub
  fild timeFrequency
  fdiv
  fmul FP4(1000.0) ; to get milliseconds instead of seconds
  fistp timeElapsed
  inkey str$(dword ptr timeElapsed), " ms elapsed"
  exit
end start

Ascended

  • Member
  • ***
  • Posts: 332
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #40 on: April 13, 2018, 06:57:49 AM »
-> Project doesn't link to ole32.lib.

CoInitialize and CoUninitialize do need ole32.lib, needed for COM.

Weird. Definitely not linking to this yet COM is working perfectly.

Maybe something in d3d11.lib?

I don't call CoInitialize or CoUnititialize anywhere either. Not even in my C++ code. Haven't had to do that since DX9. Maybe DX11 does this under the hood?


[edit]
Arggh! My bad. I am including masm32rt.inc which links to ole32.lib.

Siekmanski

  • Member
  • *****
  • Posts: 1684
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #41 on: April 13, 2018, 08:57:54 AM »
I'm just following the rules.  :biggrin:

EDIT: I'm not certain now if it is really necessary for DirectX.  ::)
I never used CoCreateInstance as far as I can remember in my DirectX code.
Only used it in DirectShow I think.

https://msdn.microsoft.com/en-us/library/windows/desktop/ms678543(v=vs.85).aspx
Creative coders use backward thinking techniques as a strategy.

LordAdef

  • Member
  • ****
  • Posts: 604
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #42 on: April 13, 2018, 09:29:19 PM »
Guys,

Allow me to keep this topic going for a bit longer.

Since Hutch, Marinus, JJ and I are going through different routes, I wonder how the benchmarks behave (not done it yet). But an interesting one though.

I'm dealing with dwords and doing the stuff in cpu prior to FPU. Marinus is going SIMD with dd, and JJ is full dq.
My approach was:

Code: [Select]
.data
    SchedulerMS dd 1 ; granularity for Sleep
PerfCountFreq dd 0
LastCounter dd 0
EndCounter dd 0
ElapsedCounter dd 0
tFPS dd 0
MSPerFrame real8 0.0
SleepMS sdword 0
TargetSecPerFrame real8 16.0


.code
inv timeBeginPeriod, SchedulerMS
.IF eax != TIMERR_NOERROR
       console "ATTENTION: timeBeginPeriod failed!" ; (console is my printf macro)
.ENDIF
inv QueryPerformanceFrequency, ADDR PerfCountFreq
inv QueryPerformanceCounter, ADDR LastCounter

; prog loop starts

         ;;; code here

inv QueryPerformanceCounter, ADDR EndCounter
mov ecx, LastCounter
mov eax, EndCounter
sub eax, ecx
mov edx, 1000
mov ElapsedCounter, eax
mul edx

push eax
fild dword ptr [esp]
fidiv PerfCountFreq
fstp MSPerFrame

mov eax, PerfCountFreq
cdq
div dword ptr ElapsedCounter
mov tFPS, eax

fld TargetSecPerFrame
fsub MSPerFrame
fistp SleepMS

cmp SleepMS, 0
jle done
inv Sleep, dword ptr [SleepMS]

done:
[code]

By natural selection, I must be running far behind...but who knows... any comments?


edit to organize the code

Siekmanski

  • Member
  • *****
  • Posts: 1684
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #43 on: April 13, 2018, 10:17:11 PM »
Quote
I'm dealing with dwords and doing the stuff in cpu prior to FPU. Marinus is going SIMD with dd, and JJ is full dq.

Yeah, everybody has his own coding style.  :badgrin:

PerfCountFreq, LastCounter, EndCounter should be QWORD size.
Now they overwrite each other and ElapsedCounter also.

Maybe better to keep it all in the FPU then you can also make a reciprocal of PerfCountFreq and get rid of the fidiv instruction and replace it with fmul.
Creative coders use backward thinking techniques as a strategy.

LordAdef

  • Member
  • ****
  • Posts: 604
Re: Help with QueryPerformanceCounter and 64 bit numbers
« Reply #44 on: April 13, 2018, 10:26:40 PM »
Quote
Maybe better to keep it all in the FPU then you can also make a reciprocal of PerfCountFreq and get rid of the fidiv instruction and replace it with fmul.

This is the Jochen! nice