Speedtest oder Gibts was schnelleres als GetTickCount_()?

Für allgemeine Fragen zur Programmierung mit PureBasic.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Speedtest oder Gibts was schnelleres als GetTickCount_()?

Beitrag von Scarabol »

Hallo Leute,

progge gerade an einem kleinen Strategiespiel.
Nun möchte ich das ganze natürlich noch optimieren, um auch im fortgeschrittenen Spiel (also viele Einheiten, Gebäude ect.) noch eine gute FPS-Rate zu erreichen.
Dazu habe ich erstmal den Code in einige Bereiche aufgeteilt, um die Stellen zu finden an denen der Code "langsam" läuft. Die Zeit die der PC für den jeweiligen Bereich brauchte hab ich dann mit GetTickCount_() ermittelt.

Nun habe ich folgendes Problem:
Die Schleife mit der meine Einheiten verwaltet werden, braucht relativ lange. Aber wie kann ich herausfinden welcher Teil der Schleife so langsam ist, da nur die gesamte Schleife eine Dauer von 16ms hat und ein einzelner Schleifendurchgang unter 1ms liegt, lässt er sich mit GetTickCount_() nicht mehr messen.
Wie kann ich Zeiten messen die unter 1ms liegen?

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
Fluid Byte
Beiträge: 3110
Registriert: 27.09.2006 22:06
Wohnort: Berlin, Mitte

Beitrag von Fluid Byte »

Die Boardsuche ist dein Freund! Bild
Windows 10 Pro, 64-Bit / Outtakes | Derek
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

unter windows kannst du QueryPerformanceCounter_() benutzen.
hier hast du eine include von mir, mit der du millisekunden genaue
antworten bekommst. wenn du den code anpasst kannst du sogar
kleinere auflösung als millisekunden erzielen.

Code: Alles auswählen

; time.pbi

; (uses win-api)



Define QPC_Time_freq.q
Define QPC_Time_start.q



 ; if an high-resolution performance counter is available
 ; the procedure initTime() returns 1, otherwise 0.
 ; it also resets the clock for getTime()
 ; [it also gets the counter-frequency needed for internal calculation in getTime()]
Procedure.l initTime()
  Shared QPC_Time_freq.q
  Shared QPC_Time_start.q
  If Not QueryPerformanceFrequency_(@QPC_Time_freq.q)
    ProcedureReturn 0
  Else
    QueryPerformanceCounter_(@QPC_Time_start.q)
    ProcedureReturn 1
  EndIf
EndProcedure


 ; getTime() returns the amount of milliseconds
 ; since the last call of initTime()
Procedure.l getTime()
  Shared QPC_Time_freq.q
  Shared QPC_Time_start.q
  Protected QPC_Time_now.q
  QueryPerformanceCounter_(@QPC_Time_now.q)
  ProcedureReturn (QPC_Time_now - QPC_Time_start)*1000/QPC_Time_freq
EndProcedure











; Debug "---- EXMAPLE - time.pbi"
; If Not initTime()
;   MessageRequester("error","no high-resolution performance counter available.")
;   End
; EndIf
; 
; While ms<1000
;   ms=getTime()
;   If ms<>last
;     out$=Str(ms)
;     If (ms-last)>1
;        out$ + " [!]" ; <<<< gelegentliche ungenauigkeit durch multiTaskOS
;     EndIf
;     Debug out$
;     last=ms
;   EndIf
; Wend
; Debug "----"


my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Hi Leute,

und danke Null für den Code. Um die Zeitmessung unterhalb einer ms durchzuführen müsste ich doch nur den 1000 sender Faktor ändern oder?

Aber in welche Richtung, ich bekom trotzdem noch merkwürdige Werte...

Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Benutzeravatar
#NULL
Beiträge: 2237
Registriert: 20.04.2006 09:50

Beitrag von #NULL »

ich habs mal angepaßt.
du kannst jetzt bei initTime() die auflösung wählen, und zwar in form
von Ticks pro sekunde. der default-wert ist 1000, also millisekunden.

Code: Alles auswählen

; time.pbi

; (uses win-api)



Define QPC_TICKS_PER_SECOND.l
Define QPC_Time_freq.q
Define QPC_Time_start.q



 ; if an high-resolution performance counter is available
 ; the procedure initTime() returns 1, otherwise 0.
 ; it also sets the resolution for getTime() (default is 1000 ticks per second -> milliseconds)
 ; it also resets the clock for getTime()
 ; [it also gets the counter-frequency needed for internal calculation in getTime()]
Procedure.l initTime(ticks_per_second.l=1000)
  Shared QPC_TICKS_PER_SECOND.l
  Shared QPC_Time_freq.q
  Shared QPC_Time_start.q
  If Not QueryPerformanceFrequency_(@QPC_Time_freq.q)
    ProcedureReturn 0
  Else
    QueryPerformanceCounter_(@QPC_Time_start.q)
    QPC_TICKS_PER_SECOND.l = ticks_per_second
    ProcedureReturn 1
  EndIf
EndProcedure


 ; getTime() returns the amount of ticks elapsed
 ; since the last call of initTime()
Procedure.l getTime()
  Shared QPC_TICKS_PER_SECOND.l
  Shared QPC_Time_freq.q
  Shared QPC_Time_start.q
  Protected QPC_Time_now.q
  QueryPerformanceCounter_(@QPC_Time_now.q)
  ProcedureReturn (QPC_Time_now - QPC_Time_start) * QPC_TICKS_PER_SECOND / QPC_Time_freq
EndProcedure











; Debug "---- EXMAPLE - time.pbi"
; If Not initTime()
;   MessageRequester("error","no high-resolution performance counter available.")
;   End
; EndIf
; 
; initTime(10) ; now we get 10 ticks per second
; While  tick < QPC_TICKS_PER_SECOND * 2 ; for two seconds
;   tick=getTime()
;   If tick<>tick_previous
;     Debug Str(tick)
;     tick_previous=tick
;   EndIf
; Wend
; 
; Debug "":Debug "########################":Debug "########################":Debug ""
; 
; initTime(100000) ; now we get 100 ticks per millisecond !
; tick=getTime()
; While tick < QPC_TICKS_PER_SECOND * 0.001 ; for one milliseconds
;   tick=getTime()
;   out$=Str(tick) + " ticks since initTime()   [" + StrF(tick/QPC_TICKS_PER_SECOND, 8) + " seconds]"
;   Debug out$
; Wend
; Debug "----" 
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
Scarabol
Beiträge: 1427
Registriert: 30.11.2005 21:00

Beitrag von Scarabol »

Super!
:allright:

Funktioniert auf Anhieb.

Danke
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea

PB-V: 4
WinXP
Antworten