Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QElapsedTimer and QTimer strange behavior
QtWS25 Last Chance

QElapsedTimer and QTimer strange behavior

Scheduled Pinned Locked Moved General and Desktop
3 Posts 3 Posters 3.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • LabanKL Offline
    LabanKL Offline
    LabanK
    wrote on last edited by
    #1

    Currently working on a project we face the following strange behavior:
    We set up a QTimer timing out each 5ms.
    We also use a QElapsedTimer measuring the time at each QTimer timeout.
    The printouts show a relative stable loop time.

    However, after exactly (!) 3497 iterations, the loop time is 4 milliseconds. This happens at exactly iteration 3497 each time the program is run, and with a cyclic behavior (it=6994, 10491, ...). The iteration may vary between computers, but occurs around that iteration (~3500).

    Either the QTimer times out too soon (at that iteration) or the time measurement (QElapsedTimer) does something strange. Could that be a quantification error? We have also checked against system time (QDateTime) and windows QueryPerformanceTimers.

    This phenomena occurs on Windows 7 64-bit only; on Linux OpenSUSE we do not see the same. We tried both Qt-4.8 and Qt-5.0 versions.

    Debug printouts:

    @"Iteration: 3495, Nanosecs: 17470502465, ns diff: 4992721, Millisecs: 17470.5, ms diff: 5.0, systime: 1372419103724"
    "Iteration: 3496, Nanosecs: 17475514952, ns diff: 5012487, Millisecs: 17475.5, ms diff: 5.0, systime: 1372419103729"
    "Iteration: 3497, Nanosecs: 17479511409, ns diff: 3996457, Millisecs: 17479.5, ms diff: 4.0, systime: 1372419103733"
    "Iteration: 3498, Nanosecs: 17484515153, ns diff: 5003744, Millisecs: 17484.5, ms diff: 5.0, systime: 1372419103738"
    "Iteration: 3499, Nanosecs: 17489533341, ns diff: 5018188, Millisecs: 17489.5, ms diff: 5.0, systime: 1372419103743" @

    Example code:

    main.cpp
    @#include <QCoreApplication>
    #include "timertester.hpp"

    int main(int argc, char *argv[])
    {
    QCoreApplication a(argc, argv);
    TimerTester time_test;
    time_test.start();
    return a.exec();
    }
    @

    timertester.hpp
    @
    #ifndef TIMERTESTER_HPP
    #define TIMERTESTER_HPP

    #include <QtCore>

    class TimerTester : public QObject
    {
    Q_OBJECT
    public:
    explicit TimerTester(QObject* parent = 0);
    void start();

    signals:

    public slots:
    void tic();

    private:
    QTimer* m_timer;
    QElapsedTimer m_elapsed_timer;

    qint32 m_iteration;
    qint64 m_base_nsec;
    qint64 m_prev_nsec;
    };

    #endif // TIMERTESTER_HPP
    @

    timertester.cpp
    @#include "timertester.hpp"

    TimerTester::TimerTester(QObject* parent) : QObject(parent)
    {
    m_timer = new QTimer(this);
    m_timer->setInterval(5);
    connect(m_timer, SIGNAL(timeout()), this, SLOT(tic()));

    m_iteration = 0;
    m_base_nsec = 0;
    m_prev_nsec = 0;
    }

    void TimerTester::start() {
    m_elapsed_timer.start();
    m_timer->start();
    }

    void TimerTester::tic() {
    //First operation, store total number of nano seconds elapsed when
    //QTimer times out
    qint64 nsecs_elapsed = m_elapsed_timer.nsecsElapsed();
    qint64 sys_time = QDateTime::currentMSecsSinceEpoch();

    //Adjust elapsed nano seconds with base line
    if(m_base_nsec == 0) {
    m_base_nsec = nsecs_elapsed;
    }
    nsecs_elapsed -= m_base_nsec;

    //Nano seconds since last QTimer time out
    //Around 5 millions if no timer slips
    qint64 nsec_diff = nsecs_elapsed - m_prev_nsec;
    m_prev_nsec = nsecs_elapsed;

    //Also present in micro seconds
    double msecs = double(nsecs_elapsed) / 1e6;
    double msec_diff = double(nsec_diff) / 1e6;
    m_iteration++;

    //Printout
    qDebug() << QString("Iteration:%1, Nanosecs:%2, ns diff:%3, Millisecs:%4, ms diff:%5, systime: %6").
    arg(m_iteration, 5).
    arg(nsecs_elapsed, 12).
    arg(nsec_diff, 8).
    arg(msecs, 8, 'f', 1).
    arg(msec_diff, 4, 'f', 1).
    arg(sys_time);
    }
    @

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Windows is a non-deterministic OS, so keeping strict time isn't a high priority for it. I'm surprised you managed to get 5 ms most of the time, actually -- Windows' system timer has a resolution of somewhere between "10ms -- 16ms":http://msdn.microsoft.com/en-us/library/windows/desktop/ms725496(v=vs.85).aspx Windows does provide "multimedia timers" that are much more precise, but I doubt QTimer uses that.

      In contrast, Linux kernels provide timers of 1ms resolution, which makes Linux QTimers ~10x more precise than their Windows counterparts.

      The periodicity of your anomalies is interesting -- I'm curious to know what causes it!

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • S Offline
        S Offline
        suswak
        wrote on last edited by
        #3

        [quote author="JKSH" date="1372434688"]Windows does provide "multimedia timers" that are much more precise, but I doubt QTimer uses that.[/quote]

        Hi. I actually found some information posted by Netich on other forums that Qt indeed uses multimedia timers. In the Qt's 4.6.0 change-log on line 111 it states:

        " - QEventDispatcherWin32 (internal class)
        * Changed the threshold for using multimedia timers to 20ms (was 10ms)."

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved