3

So, I'd like to see how long a function of in my code takes to run. (in realtime). Originally, I had this:

clock_t begin = clock();
my_function();
clock_t end = clock();
double time_spent = (double)(end - begin);

But apparently, there are some problems with this approach.

  1. It only measures the time that the cpu took to process my application.
  2. It only measures on microsecond level, from what I can see - which isn't precise enough for my case.

So, what is the proper way to get the time a function took to run? Is CPU time really the right approach? How precise can I measure? I was thinking nanosecond level?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
Kyu96
  • 1,159
  • 2
  • 17
  • 35
  • 2
    for real time you can use `gettimeofday` but no way for *nanosecond level*, and you are probably not on a real time system, so even the milli second is in fact out of the effective precision you can hope – bruno Jul 30 '20 at 10:24
  • @bruno I see. Is realtime the preferred way when benchmarking the runtime of a function? – Kyu96 Jul 30 '20 at 10:26
  • 1
    @bruno: `gettimeofday` is deprecated on systems that have it, in favour of `clock_gettime` (which does have nanosecond resolution, but practical overhead of measurement of something like tens of ns). And out-of-order execution means you can't reliably time a timed region smaller than that without knowing about your CPU, and e.g. using x86 `lfence` ; `rdtsc` to control OoO exec. See [Idiomatic way of performance evaluation?](https://stackoverflow.com/q/60291987) re: tiny timed regions. – Peter Cordes Jul 30 '20 at 10:55

2 Answers2

5

So, you should ask yourself if you really need nanosecond level. A processor run with a clock rate in the GHz order, meaning an instruction takes in the order of nanosecond to be executed. This means that nanosecond accuracy is extremely complicated (if not impossible) to measure.

There is new timespec_get that comes with C11 that can get you time with nanosecond resolution, but it is certainly not that accurate.

If your goal is to measure execution time of a function, your best option is certainly to call your function in a loop that executes it like a thousand times and you measure it with microsecond accuracy, this would certainly be closer to nanoseconds accuracy than any timer that claim to be nanoseconds.

Puck
  • 2,080
  • 4
  • 19
  • 30
  • Fair point. Yeah I think microseconds is probably enough - and then getting an average after multiple iterations. I assume realtime is the common way to measure a function runtime tho, right? – Kyu96 Jul 30 '20 at 10:47
  • @Kyu96 And no, I don't think realtime would be the way to go as it is usually precise at 1 seconds accuracy. This question was informative https://stackoverflow.com/a/368843/4049851 and I would apply the second response for your case, which measure time based on clock ticks elapsed. – Puck Jul 30 '20 at 10:58
  • 2
    Calling in a loop will measure throughput. Or if you make the next input depend on the previous output, measure latency. Microbenchmarking is *hard*, and you sometimes have to be careful to get optimized code without letting the compiler optimize away stuff you wanted to measure. related: [Idiomatic way of performance evaluation?](https://stackoverflow.com/q/60291987) – Peter Cordes Jul 30 '20 at 10:59
  • Puck: @Kyu96 is asking whether wall-clock time (aka real time) is the normal way to measure, as opposed to process CPU-time as accounted by the OS. You can measure either with high accuracy. I usually measure stuff in clock cycles, so I can be slightly sloppy about controlling CPU frequency scaling, as long as it's something that doesn't depend a lot on memory bandwidth or latency. If the thing you're measuring doesn't do any I/O, wall time and CPU time are basically equivalent on an idle system where no context switches can steal time from your process. Interrupts don't count... – Peter Cordes Jul 30 '20 at 11:04
4

The C Standard does not define a portable way to do this. The time() library function has a definition of 1 second, which is inappropriate for your purpose. As mentioned by @Puck, C11 did introduce timespec_get() to retrieve a more precise time value, but this function is not widely supported and may not provide the expected accuracy.

Other functions are available on selected systems:

  • The POSIX standard defines gettimeofday() and clock_gettime() which can return precise real time with the argument CLOCK_REALTIME.

  • OS/X has a more precise alternative: clock_gettime_nsec_np which returns a 64-bit value in nanosecond increments.

  • Microsoft documents this for Windows.

Note however that performing precise and reliable sub-microsecond benchmarks is a difficult game to say the least.

chqrlie
  • 131,814
  • 10
  • 121
  • 189