2

I am working on high accuracy timers in C++ on Windows. My application requires the timer accuracy in ms. Up to 5 ms error can be omitted in the app. I have shared the code below and I have got very good repeatability in this timer. 2 times out of 20 were error but the errors are quite big around 75 ms. What can be caused of these errors? Because whenever I run the program the error level is the same which is around 75 ms. I usually choose delay 10 ms. Is it possible to obtain ms accuracy on Windows? Thank you in advance.

#include <string>
#include <chrono>
#include <iostream>

using namespace std;

//Get the time stamp
time_t getTimeStamp()
{
    std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> tp =
    std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now());
    auto tmp = std::chrono::duration_cast<std::chrono::milliseconds>(tp.time_since_epoch());
    time_t timestamp = tmp.count();
    return timestamp;
}
//Get the time year-month-day hour-minute-second millisecond
std::string gettm(__int64 timestamp)
{
    __int64 milli = timestamp + (__int64)8 * 60 * 60 * 1000;
    auto mTime = std::chrono::milliseconds(milli);
    auto tp = std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds>(mTime);
    auto tt = std::chrono::system_clock::to_time_t(tp);
    std::tm now;
    ::gmtime_s(&now, &tt);
    char res[64] = { 0 };
    sprintf_s(res, _countof(res), "%03d",static_cast<int>(milli % 100));
    return std::string(res);
}

int main(void)
{   
   bool state = false;
   int delay;
   cout << "Delay (ms): " << endl;
   cin >> delay;
   Again:
      string now = gettm(getTimeStamp());
      int now_int = stoi(now);
      int sss = now_int + delay;
      if (sss >= 100)
         sss = sss % 100;
      while(1)
      {
         string change = gettm(getTimeStamp());
         int now_change = stoi(change);
         if (now_change >= 100)
             now_change = now_change % 100;
         state = true;
         cout << "High O4 and now (ms): "<< sss << " and change (ms): "<<now_change <<endl;
         if (now_change == sss) 
         {
            state = false;
            cout << "Low O4" << endl;
            goto Again; 
          }
      }

   return 0;
}
  • 3
    It is hard to say in a specific case but the `std::chrono::system_clock` is often adjusted in the background by the OS as it keeps it synchronized with *internet time* via time-servers. For timing purposes, the `std::chrono::steady_clock` is usually recommended. But that doesn't track absolute calendar time. – Galik Jul 20 '21 at 09:30
  • Could you try running your app while you have Google Chrome/Chromium browser running in your background? By default (system-wide) system clock on Windows has a tick rate tick set to 15.625 milliseconds, but running some apps (like Google Chrome) decrease it (in case of Chrome - to 1ms). – Kaznov Jul 20 '21 at 09:53
  • @Kaznov thank you for the solution, but I am not allowed to use another program to increase the precision. – Oguz Kahraman Jul 20 '21 at 10:44
  • 1
    You can increase the precision yourself with Windows API (it increases power consumption a bit). This is just for a test, to check if this solution could work. You can find more about this API in this answer: https://stackoverflow.com/questions/7685762/windows-7-timing-functions-how-to-use-getsystemtimeadjustment-correctly/11743614#11743614 – Kaznov Jul 20 '21 at 10:57
  • Also, running Chromium might not change anything, I just found out that since Windows 10 update 2004 changing time rate in one process does not affect global time rate. – Kaznov Jul 20 '21 at 10:58
  • Thanks again, it looks very useful. – Oguz Kahraman Jul 20 '21 at 12:13
  • Do you need precision or accuracy? – IInspectable Jul 22 '21 at 17:24
  • @IInspectable I need accuracy. – Oguz Kahraman Jul 23 '21 at 06:38
  • Use performance timers. – Michael Chourdakis Jul 23 '21 at 06:47

0 Answers0