0

In the following code, I repeatedly call std::chrono::high_resolution_clock::now twice, and measure the time it took between these two calls. I would expect this time to be very small, since there is no other code is run between these two calls. However, I observe strange behavior.

For small N, the max element is within a few nanoseconds, as expected. However, the more I increase N, I get very large outliers, and have gotten up to a few milliseconds. Why does this happen?

In other words, why does the max element of v increase as I increase N in the following code?

#include <iostream>
#include <vector>
#include <chrono>
#include <algorithm>

int main()
{
    using ns = std::chrono::nanoseconds;
    
    uint64_t N = 10000000;
    std::vector<uint64_t> v(N, 0);
    for (uint64_t i = 0; i < N; i++) {
        auto start = std::chrono::high_resolution_clock::now();
        v[i] = std::chrono::duration_cast<ns>(std::chrono::high_resolution_clock::now() - start).count();
    }
    
    std::cout << "max: " << *std::max_element(v.begin(), v.end()) << std::endl;
    
    return 0;
}
  • 1
    Other things happen in your machine, which might have higher priority than your program. For example, on my machine there are 1500 threads running, and I'm just browsing this. The longer the program runs, the higher the probability of something happening. – BoP Jan 23 '23 at 19:25
  • One possibility is that when you increase your runtime length you increase the the chances of your process might be suspended so that the OS can do some other work. FWIW if you are trying to benchmark some code, you'll really want to use a dedicated tool for it like Google Benchmark. Benchmarking is very hard to get right as there are so many thing that can be optimized away by todays compilers. – NathanOliver Jan 23 '23 at 19:26
  • Side note: Don't time with `high_resolution_clock`. It prizes resolution above stability and may use a backing clock that does timing-incompatible things like go backward in time. One of the people who created it [recommends never using `high_resolution_clock` at all](https://stackoverflow.com/a/37440647/4581301). – user4581301 Jan 23 '23 at 19:29

1 Answers1

1

The longer you run your loop, the more likely it is that your OS will decide that your thread has consumed enough resources for the moment and suspend it. And the longer you run your loop, the more likely it is that this suspension will happen between those calls.

Since you're only looking at the "max" time, this only has to happen once to cause the max time to spike into the millisecond range.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • Off topic. Somebody asked you for a comment on this [question](https://stackoverflow.com/questions/14909796/simple-pass-through-geometry-shader-with-normal-and-color) over a year ago and you didn't reply. – sanitizedUser Jan 23 '23 at 22:29