PDA

View Full Version : How reliable are QTimers on Windows?



Cruz
20th February 2009, 12:17
Hello,

I would like to execute a function on a Windows machine as close to every 12 ms as somehow possible. Right now I'm using a QTimer and I'm not sure how well it does the job. The following test setup:



constructor
{
stepTimer = new QTimer(this);
connect(stepTimer,SIGNAL(timeout()), this, SLOT(tick()));
stepTimer->start(12);

time = new QTime();
time->start();
}

void tick()
{
qDebug() << time->restart();
}



shows that the tick() function is executed every 15 or 16 milliseconds. The output is like:

15,16,15,16,15,16,15,16,15,16,15,16,15,16....

When I start the timer with 10 ms instead of 12, I get:

0,16,15,0,16,15,0,16,15,0,16,15,0,16,15...

This is not exactly satisfactory.


First of all, how exact are the timings that QTime::restart() is showing me?

Of course it's very clear that tick() should execute in less than 12 ms and I believe qDebug() does so, but I better ask than be wrong?

I know that Windows is not a real time OS and my own experiments show that it delivers a precision somewhere around the 10 ms mark. Does anyone have more exact information?

And last but not least, what can I do to get the 12 ms rhythm as steady as possible?

seneca
20th February 2009, 12:49
QTimer is absolutely not suited for that job. (It works on the event queue)


And last but not least, what can I do to get the 12 ms rhythm as steady as possible?

This is the easiest to answer: You cant, because as you noticed it is not a real time operating system.

The nearest you can get is to write a (hight priority) windows device driver....

neuron
20th February 2009, 19:48
And last but not least, what can I do to get the 12 ms rhythm as steady as possible?

I'd run up a seperate thread and lock that one instead of trying to go through an event loop.

stevey
22nd February 2009, 23:50
I believe the smallest time you can respond to anyway on most OS's is 50ms. Anyone disagree with this?

spud
23rd February 2009, 09:46
I believe the smallest time you can respond to anyway on most OS's is 50ms. Anyone disagree with this?
You can absolutely except better precision than that. As someone suggested I would set up a separate thread which polls the time and sleeps. Do a google search for "high performance timer".
http://frank.mtsu.edu/~csjudy/directX/HighPerformanceTimer.html

Cruz
23rd February 2009, 10:55
Regarding the suggestion of using a seperate thread, why should I do that? Is a sleep based control more precise, than a timer based control? My guts say that it isn't, because you never now when a thread will be woken up again and it might have slept too long.

I think the trade off between having a faster timer and the complication plus windows dependency of the code is not worth it for me. I can live with 16 ms as long as the rhythm is steady. The most important criterion is that every iteration should take an equal amount of time.

So the question that hasn't been addressed yet is, how precise are the timings that I get from QTime? When it says 16 ms, has it really been 16 ms? Or something between 10 and 20?

spud
23rd February 2009, 11:53
So the question that hasn't been addressed yet is, how precise are the timings that I get from QTime? When it says 16 ms, has it really been 16 ms? Or something between 10 and 20?

On XP+ between 10 and 20 ms. on NT between 0 and 50 ms, assuming the GUI thread isn't too busy.

Cruz
3rd March 2009, 21:29
Hm, here (http://doc.trolltech.com/4.3/porting4.html#qtimer) it says that QTimer now uses the multimedia timer API on Win XP and it should have a 1 ms resolution. That sounds good actually. But then how come that my measurements in my OP report 16 ms instead of 12? Could it be that the gui thread takes that long to process events before it can fire the timer? Or is it because the answer from Qtime::restart() is not precise?

seneca
3rd March 2009, 22:36
You should try to understand the difference between windows and a real time operation system, for example QNX. No matter how hard you try, an application will NEVER be able to answer or process any request exactly per millisecond:

Besides your application, many other applications and system processes are running at same time sharing all the same processor and memory, and the scheduler will assign time to them in a non-tranparent way (non-transparent for the application). There is absolutely no guarantee that your application will get any processing time at all between two of your ticks. This is something beyond the scope of Qt (or any other application framework).