PDA

View Full Version : suggestion needed for qglwidget performance timer



papillon
29th September 2011, 00:41
I'm building a Qt4.7 application that contains a qglwidget, and I'd like to have a custom performance timer in order to have smooth rotations, translations etc.

In the qglwidget paintGL routine I have:

myTimer.start(); // initialized as QTime myTimer
DrawEverything();
int elapsed=myTimer.restart();

elapsed should contain the number of milliseconds needed to DrawEverything(). However, if the scene is empty I get a value of 16, if the opengl scene is filled with about 10000 display lists (which causes the gl viewport to be quite slow), the elapsed value is only 18, while it should be much higher, considering the amount of geometry to be drawn.
I thought that maybe QTime would probably skip time lost in opengl operations, so I decided to create a custom timer (getTimeOfDay and similar), but the results are the same.
Anybody successfully created a performance timer to be used with a qglwidget?
Thanks

moe
29th September 2011, 07:26
We use the following (platform dependent, Linux) for profiling OpenGL code, which returns a time-stamp in nanoseconds.


#include <time.h>

inline uint64_t performanceCounter() {
timespec timebase;
clock_gettime(CLOCK_MONOTONIC,&timebase);
return static_cast<uint64_t>(timebase.tv_sec)*1E9+timebase.tv_nsec;
}

papillon
29th September 2011, 09:04
Thanks moe, and do you read start and end time at the beginning and end of the draw function as I also do?

moe
29th September 2011, 09:42
Yes, and also at various other places. We use this to profile the code doing the drawing and the preprocessing done before drawing.

Piskvorkar
12th November 2012, 15:48
The main problem could be that your drawing is done on GPU. You should call glFinish() before start and before end of measuring to ensure that CPU will wait for GPU. Otherwise you are not measuring drawing but only calls to GPU.



glFinish();
myTimer.start(); // initialized as QTime myTimer
DrawEverything();
glFinish();
int elapsed=myTimer.restart();


As a multiplatform solution you can use Embedded Profiler (http://www.embeddedprofiler.com) (free for Windows and Linux) which has a higher resolution. It has an interface to timer in a processor cycle count units and can give you a number of cycles per seconds:



EProfilerTimer timer;
glFinish();
timer.Start();
... // your OpenGL code here
glFinish();
const uint64_t number_of_elapsed_cycles = timer.Stop();
const uint64_t nano_seconds_elapsed =
mumber_of_elapsed_cycles / (double) timer.GetCyclesPerSecond() * 1000000000;


Note:
Recalculation of cycle count to time is possibly a dangerous operation with modern processors where CPU frequency can be changed dynamically. Therefore to be sure that converted times are correct, it is necessary to fix processor frequency before profiling.