compile your exe as console
example results for the procedures foo bar and main
To use just add BeginProfile and EndProfile blocks, they will only compile in if #ENABLE_PROFILE=1CPU Frequency 2.75 ghz
foo sum time 685 ms avg cycles 18,614,901 0
main sum time 685 ms avg cycles 1,861,570,995 0
bar sum time 677 ms avg cycles 18,396 0
main elapsed ms check 686
press any key to end
see example
Procedure bar()
Protected b
BeginProfile("bar") ;add this and the procedure name it will only compile if #ENABLE_PROFILE=1
For a = 1 To 10000
b*a
Next
Endprofile("bar")
EndProcedure
Code: Select all
;Time profiler
;Author Idle
;PB LTS 6.01 x86,x64 asm and c backend
;v1.01b
;Notes Cycle counts are indicative of relative performance and times are approximate
;If the time cpu time stamp rolls over it subtracts from the count and adds to the err
;compile As console
#ENABLE_PROFILE=1 ;Enables profiler or to disable ENABLE_PROFILE=0
CompilerIf #ENABLE_PROFILE=1
CompilerIf Defined(PB_Compiler_Backend,#PB_Constant)
CompilerIf #PB_Compiler_Backend=#PB_Backend_C
Procedure GetRDTSC()
Protected t.q
!unsigned hi, lo;
!__asm__ __volatile__ ("lfence\n rdtsc\n lfence" : "=a"(lo), "=d"(hi));
!v_t =((unsigned long long)lo)|(((unsigned long long)hi)<<32 );
ProcedureReturn t
EndProcedure
CompilerElse
Procedure.q GetRDTSC()
Protected hi.q,lo.q,res.q
DisableDebugger
!lfence
!rdtsc
!lfence
!mov [p.v_hi], edx
!mov [p.v_lo], eax
res = hi
res << 32
res | lo
ProcedureReturn res
EnableDebugger
EndProcedure
CompilerEndIf
CompilerElse
Procedure.q GetRDTSC()
Protected hi.q,lo.q,res.q
DisableDebugger
!lfence
!rdtsc
!lfence
!mov [p.v_hi], edx
!mov [p.v_lo], eax
res = hi
res << 32
res | lo
EnableDebugger
EndProcedure
CompilerEndIf
Procedure.q GetFrequency()
Protected t1.q,t2.q,result
Repeat
t1 = GetRDTSC()
Delay(128)
t2 = GetRDTSC()
If t2 - t1 > 0
result = ((t2-t1) / (128))
Break
EndIf
ForEver
ProcedureReturn result
EndProcedure
Structure profile
count.i
err.i
sumtime.q
st.q
et.q
EndStructure
Global NewMap prof.profile()
Global prof_msfreq.i = GetFrequency()
Macro BeginProfile(name)
prof(name)\count + 1
prof(name)\st = GetRDTSC()
EndMacro
Macro EndProfile(name)
prof(name)\et = GetRDTSC()
If prof(name)\et > prof(name)\st
prof()\sumtime + prof(name)\et - prof(name)\st
Else
prof()\count - 1 ;ignore rollover if st > et
prof()\err + 1 ;indicates a timeing error
EndIf
EndMacro
Macro PrintProfile()
PrintN("CPU Frequency " + FormatNumber(prof_msfreq/1000000.0,2,".",",") + " ghz")
ForEach prof()
If prof()\count
PrintN(MapKey(prof()) + " sum time " + FormatNumber(prof()\sumtime / prof_msfreq ,0,".",",") + " ms avg cycles " + FormatNumber(prof()\sumtime / prof()\count,0,".",",") + " " + Str(prof()\err ))
EndIf
Next
EndMacro
CompilerElse
Macro BeginProfile(name) : EndMacro
Macro EndProfile(name) : EndMacro
Macro PrintProfile() : EndMacro
CompilerEndIf
CompilerIf #PB_Compiler_IsMainFile
;example
Procedure bar()
Protected b
BeginProfile(#PB_Compiler_Procedure) ;Add BeginProfile / EndProfile blocks to code you want to time it will only compile if #ENABLE_PROFILE=1 is declared
For a = 1 To 10000
b*a
Next
EndProfile(#PB_Compiler_Procedure)
EndProcedure
Procedure foo()
Protected b
BeginProfile(#PB_Compiler_Procedure)
For a = 1 To 1000
b * 2
bar()
Next
EndProfile(#PB_Compiler_Procedure)
EndProcedure
OpenConsole()
BeginProfile(#PB_Compiler_Procedure)
st = ElapsedMilliseconds()
For a = 1 To 100
foo()
Next
et = ElapsedMilliseconds()
EndProfile(#PB_Compiler_Procedure)
PrintProfile() ; dump profile results
PrintN("main elapsed ms check " + Str(et-st))
PrintN("press enter key to end")
Input()
CompilerEndIf