-1

I'am trying to make a time meter. My OS is Windows.
Here is a small piece of code that gives a strange result.
If a thread sleeps for 1ms and does this 5000 times, then I would expect it to take roughly 5 seconds.
But I get as a result that test_time = 12.8095
Do not understand why?
How can I fix the code so that I get a time meter that can measure durations of about 1 millisecond?

std::atomic_bool work = true;
    size_t cnt{};
    std::chrono::duration<double> operation_time;
    double test_time;
            auto start_time_ = std::chrono::high_resolution_clock::now();
            std::thread counter_ = std::thread([&work, &cnt]() {
                while (work) {
                    std::this_thread::sleep_for(std::chrono::milliseconds(1));
                    cnt++;
                    if (cnt >= 5000)
                        work = false;
                }
                });
            
            if (counter_.joinable())
                counter_.join();
            operation_time = std::chrono::duration<double>(std::chrono::high_resolution_clock::now() - start_time_);
            test_time = operation_time.count();

            std::cout << "test_time = " << test_time << std::endl;
SuperPuper
  • 51
  • 1
  • 1
  • 5
  • 5
    The operating system you are running this program on is probably not a hard realtime OS, and won't be able to wake a thread up after precisely 1 ms. E.g. on Windows the system clock resolution could be as coarse as 15ms, meaning that `sleep` always sleeps at least this long. Regarding "how to fix this code" - that rather depends on what ultimate goal you are trying to achieve. – Igor Tandetnik Jun 20 '22 at 21:19
  • @IgorTandetnik, yes my OS is Windows. My goal is to count how long a function takes to run. But I need to do this by starting my timer. Those, in this question I'am trying to make a time meter – SuperPuper Jun 20 '22 at 21:30
  • 1
    May-or-may not be related, but one of the people most responsible for `std::chrono::high_resolution_clock` [warns against its use](https://stackoverflow.com/a/37440647/4581301). Be absolutely certain you're getting the type of time you need. – user4581301 Jun 20 '22 at 21:33
  • 1
    You won't be able to precisely measure very short time intervals. If you are trying to perform benchmarks, measure how long it takes to run the code `N` times for some large value of `N`. Or, use some benchmarking framework. – Igor Tandetnik Jun 20 '22 at 21:37
  • Expanding on Igor Tandetnik's comment above a sleep function typically promises only that the sleep will last AT LEAST as long as requested. [`std::this_thread::sleep_for`](https://en.cppreference.com/w/cpp/thread/sleep_for) makes exactly this guarantee. You have to be able to survive sleeping one timer tick, plus any scheduling jitter, longer than requested, and as Igor pointed out, a timer tick can be brutally long (when viewed from the lens of 1 ms, at any rate) – user4581301 Jun 20 '22 at 21:40

1 Answers1

0

As previously stated, sleep_for

Blocks the execution of the current thread for at least the specified sleep_duration.

The answer to your question would be to use sleep_until

Blocks the execution of the current thread until specified sleep_time has been reached.

That means, take the current timestamp, add 1 ms and sleep until that time.

See:

Erdal Küçük
  • 4,810
  • 1
  • 6
  • 11