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. High Resolution Timer
Forum Updated to NodeBB v4.3 + New Features

High Resolution Timer

Scheduled Pinned Locked Moved General and Desktop
9 Posts 4 Posters 17.2k Views 1 Watching
  • 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.
  • V Offline
    V Offline
    vezprog
    wrote on last edited by
    #1

    Does anyone know of any 'reliable' high resolution timers for Windows / Linux that can be used within Qt? My target platforms currently are Windows / Linux.

    Basically, the functionality I am looking for (for accurate / consistant looping in a thread), is a timer with resolution of 1mS or better that I can:

    SetType(int type, int mS) // periodic / or one shot
    Start() // start the timer
    Clear() // stop the timer
    Wait() // wait for the remaining amount of time left on the timer (blocking call)
    Poll() // poll the timer to see if the timer has elapsed

    I can do this on Linux using a non-qt solution with posix timerfd / poll() and get microseconds resolution, but for what I am reading about windows, it is all dependent on the system hardware (I can always wrap the linux stuff in an ifdef PLATFORM, but theres still windows).

    QElapsed timer can be manipulated to what I need minus the wait() for time to finish, but can anyone say that the resolution of QElapsed timer is indeed 1mS or less independent of the system hardware with windows?

    I know there is a lot that comes into play with timing but I was hoping someone might have a solution... Thank you!

    1 Reply Last reply
    0
    • S Offline
      S Offline
      Seba84
      wrote on last edited by
      #2

      I am not an expert on the subject, but I see in "QElapsedTimer documentation":http://qt-project.org/doc/qt-4.8/qelapsedtimer.html#details that there is a high resolution clock special for Windows.

      QElapsedTimer::PerformanceCounter
      The high-resolution performance counter provided by Windows. This clock is monotonic and does not overflow.

      Why don't you try it?

      1 Reply Last reply
      0
      • V Offline
        V Offline
        vezprog
        wrote on last edited by
        #3

        Well, I have looked at the source code for QElapsedTimer already and it uses QueryPerformanceFrequency / QueryPerformanceCounter which from the looks of all of the forum posts online, both of those are limited because of hardware.

        This is what I am working with so far:
        @
        #ifndef HIGHPRECISIONTIMER_H
        #define HIGHPRECISIONTIMER_H

        #include "utility_global.h"
        #include <QObject>
        #include <QElapsedTimer>
        #include <QMutex>
        #include <QWaitCondition>

        // high precision timer class
        class UTILITYSHARED_EXPORT HighPrecisionTimer : public QObject
        {
        Q_OBJECT

        QMutex _waitMutex;
        QWaitCondition _waitSleep;
        

        public:
        HighPrecisionTimer(QObject *parent = 0);
        bool setInterval(int ms);
        int msInterval();
        void start();
        void wait();
        bool poll();
        void restart();
        QElapsedTimer timer();

        private:
        void blockingSleep(unsigned long ms);

        QElapsedTimer _timer;
        qint64 _interval;
        qint64 _reference;
        

        };

        #endif // HIGHPRECISIONTIMER_H

        #include "highprecisiontimer.h"
        #include <QDebug>

        /*
        // class constructor
        */
        HighPrecisionTimer::HighPrecisionTimer(QObject *parent) :
        QObject(parent)
        {
        _interval = 0;
        _waitMutex.lock();
        }

        /*
        // set interval (public function)
        */
        bool HighPrecisionTimer::setInterval(int ms)
        {
        if (!_timer.isValid()){
        _interval = ms;
        return true;
        }
        else
        return false;
        }

        /*
        // millisecond interval (public function)
        */
        int HighPrecisionTimer::msInterval()
        {
        return _interval;
        }

        /*
        // start high precision timer (public function)
        */
        void HighPrecisionTimer::start()
        {
        _timer.start();
        _reference = _timer.elapsed();
        }

        /*
        // wait until elapsed time has been triggered (public function)
        */
        void HighPrecisionTimer::wait()
        {
        // calculate the remaining time left
        qint64 elapsedTime = _timer.elapsed();
        qint64 leftOver = _interval - (elapsedTime - _reference);

        // if the difference is positive, then sleep for remaining time
        if (leftOver > 0)
            blockingSleep(leftOver);
        
        // new reference
        _reference = _timer.elapsed();
        

        }

        /*
        // restart timer (public function)
        */
        void HighPrecisionTimer::restart()
        {
        _timer.restart();
        }

        /*
        // blocking sleep (private function)
        */
        void HighPrecisionTimer::blockingSleep(unsigned long ms)
        {
        _waitSleep.wait(&_waitMutex, ms);
        }

        /*
        // poll the timer to see if it has expired (public function)
        */
        bool HighPrecisionTimer::poll()
        {
        // calculate the remaining time left
        qint64 leftOver = _interval - (_timer.elapsed() - _reference);

        // if the difference is positive, then sleep for remaining time
        if (leftOver > 0)
            return false;
        else
            return true;
        

        }

        /*
        // return the timer (public function)
        */
        QElapsedTimer HighPrecisionTimer::timer()
        {
        return _timer;
        }
        @

        1 Reply Last reply
        0
        • JeroentjehomeJ Offline
          JeroentjehomeJ Offline
          Jeroentjehome
          wrote on last edited by
          #4

          But the question is WHY do you need the high resolution timer? In basic the OS will only call your application ones every 1..15msec depending on the "free" time of the CPU. Therefor every Event set (timerEvent) is only handled then. So a "slow" 5msec timer is also too quick for a normal working Windows machine. All timers below 10msec are usually not running on time.
          Maybe If we understand what you need to achieve we are able to better assist you and give alternatives. Sometimes the solution will come with a different approach ;-)

          Greetz, Jeroen

          1 Reply Last reply
          0
          • V Offline
            V Offline
            vezprog
            wrote on last edited by
            #5

            I apologize for the confusion and my vagueness.

            Basically, I created a Qt Console application that contains 3 Qt Dll's. When everything starts up, I gather some information from the inifile to see what Dll's are going to be used.

            Each Dll has one main function that gets run in a thread (I could use QThread and use the Run() method, but I wanted custom input arguments). I am basically creating a sub process, but one I can keep track of using Qt Concurrent.

            The threads will run / loop for the life of the application.

            For example
            @
            /*
            // spawned by Qt Concurrent
            */
            int some_process_in_dll( ... input arguments)
            {
            // this is where I thought I would setup my high precision timer
            // set its desired time
            timer->setTime(5);
            timer->start();

            while (1){
            // main process occurs here
            // for example, send tcp data
            // receive tcp data....etc.
            //
            // say this takes...2 mS to do

               // wait if there is any leftover time, in this example it would wait/block for 3 mS
               timer->wait();
            

            }
            }
            @

            The wait is very important, so I can delay for the remaining time left over. If there isn't any time leftover and the process took more than 5mS then It will not block and just loop again.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              Seba84
              wrote on last edited by
              #6

              Why do you want the timer to loop every 5ms?

              1 Reply Last reply
              0
              • V Offline
                V Offline
                vezprog
                wrote on last edited by
                #7

                Because I have to update an external device every 5mS and it needs to be a steady stream of data. Furthermore, all threads need to have the same loo time to be in sync.

                1 Reply Last reply
                0
                • JeroentjehomeJ Offline
                  JeroentjehomeJ Offline
                  Jeroentjehome
                  wrote on last edited by
                  #8

                  Again, everything below 10 msec is FAST if using a Win machine. It might operate properly if timers below this are used, but for realtime operation this is a rule of thumb. If using embedded Linux etc you could go much faster because the overhead of the OS is limited. But I lost your first question here. If the 5msec timer is set it will trigger the timeout signal, no problem. When the timer expires twice before the thread is complete it will run again, so you won't miss a data transmission to your external device. Not really a problem there, unless your external device already fails because of the delay between sending data?
                  Your solution will never work, you state in your comment that you execute a "main" in the thread that takes 2 msec or about that, but you have 3 thread + your main thread running, so how is the OS every going to do it all in time? Your execution of code already exceeds 6 msec!
                  Maybe a solution might be to have all the "main" codes in a single thread. In here you parse the data from/to the data thread via signals/slots. In the data thread only have a timer and a send/receive data to parse the data. This will minimize the cpu load of the threads, but might cause "older" data to be send to the external device.

                  Greetz, Jeroen

                  1 Reply Last reply
                  0
                  • B Offline
                    B Offline
                    belab
                    wrote on last edited by
                    #9

                    I found this nice "summary...":http://www.boost.org/doc/libs/1_54_0/libs/timer/doc/cpu_timers.html#Timer-accuracy

                    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