Inline profiler v0.1

BlitzMax Forums/BlitzMax Programming/Inline profiler v0.1

teamonkey(Posted 2005) [#1]
Hi

I found myself in need of a profiler so I thought I'd write one.

What you do is create little "samples" that you start before the code you want to profile and stop just afterwards. Then every so often you gather all the sample data together and it should calculate a rough average of how long your program spends doing certain tasks.

Usage:
mySample:TProfSample = CreateSample("A Useful Name")

StartSample(mySample)
' Code you want to investigate
StopSample(mySample)


Profile()    ' Gathers the information together (it only updates it every second or so)

ShowProfInfo()    ' Uses DrawText to display it on screen


It is not accurate by any means. It works best if you let it sample the same task many times, which is why Profile() lets the data build up over a second or so before recording it. The Millisecs timer only has a resolution of about 10ms and your sample is not going to take that long, so the only way to do it is to take an average. It should still be useful though.


Here we go...

profiler.bmx:



And here's the firepaint demo modified to demonstrate the profiler (try pressing the mouse button). F12 toggles the profile display on and off.



Robert(Posted 2005) [#2]
You can use QueryPerformanceCounter on Windows to get more accurate time information. Windows code below - I am not sure what the Linux and Mac equivilents are:


Framework BRL.GLMax2D
Import BRL.PNGLoader

Extern "Win32"
       Function QueryPerformanceFrequency:Int(freqency:Long Ptr)
       Function QueryPerformanceCounter:Int(frequency:Long Ptr)
End Extern

Graphics 1024,768,0

image:TImage=LoadImage("graphics/ship_light.png")

SetScale 0.1,0.1

Global gameSpeed:Long=0
Global oldGameSpeed:Long=0

r=QueryPerformanceFrequency(Varptr gameSpeed)

QueryPerformanceCounter(Varptr oldGameSpeed)

Global fps:Long
Global totalFps:Long=0
Global totalR:Long=0

Repeat

       For x=0 To 20
               For y=0 To 20
                       DrawImage image,x*50,y*50
                       SetRotation rotate
                       rotate :+ 3
               Next
       Next

       Flip

       Cls

       fps=(gameSpeed-oldGameSpeed)/100
       oldGameSpeed=gameSpeed

       QueryPerformanceCounter(Varptr gameSpeed)

       totalR = totalR+1

       If (totalR > 50)

       totalFps :+ fps

       EndIf
Until KeyHit(KEY_ESCAPE)

       Print (totalFps/(totalR-50))

EndGraphics



teamonkey(Posted 2005) [#3]
You can use QueryPerformanceCounter on Windows to get more accurate time information.

Thanks, I'll try adding that. I'm pretty sure there's a high-resolution timer in /proc under Linux, but last time I played about with that stuff you needed to be root to access it. No idea how to get more accurate timing on the Mac.


Robert(Posted 2005) [#4]
gettimeofday() is supposed to be accurate to around one microsecond. There are probably more advanced timers, and I don't know whether that is what millisecs already uses on Linux.


Blueapples(Posted 2010) [#5]
Pretty slick, this just helped me quickly find a few bottlenecks.