What's the relationship between the real CPU frequency and the clock_t in C?
Asked Answered
B

3

6

What's the relationship between the real CPU frequency and the clock_t (the unit is clock tick) in C?

Let's say I have the below piece of C code which measures the time that CPU consumed for running a for loop.
But since the CLOCKS_PER_SEC is a constant value (basically 1000,000) in the C standard library, I wonder how the clock function does measure the real CPU cycles that are consumed by the program while it runs on different computers with different CPU frequencies (for my laptop, it is 2.6GHz).

And if they are not relevant, how does the CPU timer work in the mentioned scenario?

#include <time.h>
#include <stdio.h>
int main(void) {
  clock_t start_time = clock();    
  for(int i = 0; i < 10000; i++) {}
  clock_t end_time = clock();
  printf("%fs\n", (double)(end_time - start_time) / CLOCKS_PER_SEC); 
  return 0;
}
Bailiwick answered 9/1, 2022 at 7:39 Comment(6)
It relates by the uhh, current ratio? Timing is provided by fixed sources, eg oscillator circuits. As most modern CPUs have dynamic frequencies, it would be impossible to have reliable timing “based on” the CPU frequency.Gerianne
What makes you think that measuring/knowing/using the CPU cycles is involved? For providing the elapsed time, it is only necessary to measrure the time. Reading a hardware timer would be one way to do so. Note that even if you would know the used CPU cycles, calculating the elapsed time from that info is near impossible nowadays, in the presence of pipelines, parallelisms, interrupts, branch prediction and whatnot.Towel
CLOCKS_PER_SEC simply gives the unit of measurement for the value returned by clock(). It isn't "basically 1000,000" but whatever the OS/compiler decide it should be. For example on my system it is 1000. That's one reason why it is a fairly blunt tool for timing purposes - it's granularity will vary from one system to another.Irvin
I think we might be looking at a meta.stackexchange.com/questions/66377/what-is-the-xy-problem Please consider whether you actually want to discuss how clock() works or whether you might indeed want to know how to measure the CPU ticks spent on the current program. Or maybe how to measure the time spent on the current program in a multithreading (possibly multi-CPU) environment. Those are different questions and you should ask the one you want answered, instead of getting lost on a detail which you think will give you the answer.Towel
However, if you actually want a different question answered than asked here, please keep this one as it is (with its upvoted answers) and create a separate new question post. Instead of fundamentally changing this one, thereby invalidating the answers.Towel
@Towel I opened another question: #70640495Bailiwick
L
7

Effectively, clock_t values are unrelated to the CPU frequency.

See longer explanation here.

While clock_t-type values could have, in theory, represented actual physical CPU clock ticks - in practice, they do not: POSIX mandates that CLOCKS_PER_SEC be equal to 1,000,000 - one million. Thus the clock_t function returns a value in microseconds.

Lelialelith answered 9/1, 2022 at 8:0 Comment(1)
It's necessary for it to be some fixed constant for binaries compiled on one system to work on another. Even back in the days of fixed CPU frequency, different systems of the same architecture could have different core clock frequencies. And anyway, it's a software clock, incremented by timer interrupts or accounted on context switches, not derived directly from core clock cycles in normal implementations.Supervise
A
3

There is no such thing as "the real CPU frequency". Not in everyone's laptop, at any rate.

On many systems, the OS can lower and raise the CPU clock speed as it sees fit. On some systems there is more than one kind of central processor or core, each with a different speed. Some CPUs are clockless (asynchronous).

Because of all this and for other reasons, most computers measure time with a separate clock device, independent from the CPU clock (if any).

Allonym answered 9/1, 2022 at 9:18 Comment(0)
T
1

For providing the information used in the shown code, measuring/knowing/using the CPU cycles is not relevant.

For providing the elapsed time, it is only necessary to measure the time.
Reading a hardware timer would be one way to do so.
Most computers (even non-embedded ones) do contain timers which are especially counting ticks of a clock with known constant frequency. (They are specifically not "CPU timers".)
Such a timer can be read and yields a value which increases once per tick (of constant period). Where "known period" means a period know to some appropriate driver for that timer, simplified "known to the clock() function, not necessarily known to you".

Note that even if the number of used CPU cycles were known, calculating the elapsed time from that info is near impossible nowadays, in the presence of:

  • pipelines
  • parallelisms
  • interrupts
  • branch prediction

More things influencing/preventing the calculation, from comment contribution:

frequency-scaling, temperature throttling and power settings (David C. Rankin)

Towel answered 9/1, 2022 at 8:1 Comment(11)
:-) I assume you do not mind me using that for extending the list. Thanks. @DavidC.RankinTowel
@DavidC.Rankin Interesting that you also leave out "cache". I did so intentionally, reasoning that while they can and usually do influence the number of CPU cycles and the resulting duration/time, they do not influence the ratio cycles/time. I guess you thought similarily.Towel
Aside ... I just went and checked and I have an old i7-2620M that bounces between 760MHz and 3.2GHz moment by moment. The CPU freq. would provide no useful info at all.Holdall
So, how does the CPU timer work in the mentioned scenario?Bailiwick
@JasonYu I added some lines on that.Towel
So, you mean the timer is not part of the CPU? But in this case, how does the clock know when the CPU is scheduled to run the current program? Since the clock function only records the time consumption of each individual CPU that executes the current program. Meaning in a multi-threaded program, the returned value would be higher than the wall-clock time.Bailiwick
"how does the clock know when the CPU is scheduled to run the current program?" I think it does not - and that it is a feature. "in a multi-threaded program, the returned value would be higher than the wall-clock time" Your understanding and mine are different here. If clock only would measure time while the CPU is processing the given program, then the measured time would be shorter than wall clock, not longer. Even if my understanding is wrong. Your phrasing of your understanding seems inconsistent to me.Towel
@Towel You are right, it would be shorter. My mistake.Bailiwick
I stay with basically "wall clock time". You do not have to trust me. But you should probably clarify what you want to discuss, see my comment on the question. Then others can give an answer which is immediatly helpful to you. And they might contradict me and I learn something....Towel
(Wide) pipelines, branch prediction, and instruction-level parallelism aren't problems for determining elapsed time from core clock cycles. If some code takes a million cycles, and you happen to know the clock was ticking at an average of 1GHz over that period, that's 1 millisecond. Regardless of how many of those cycles were wasted due to mispredicts, or got multiple instructions executed on a wide pipeline. Those would be concerns if you were trying to predict performance from a known sequence of instructions, but you're proposing that you already have a cycle count measurement.Supervise
The problems are variable CPU frequency, and if you want to not count interrupts (but do want to count kernel time in system calls). I suspect that most systems do count interrupt-handler time against the current task, instead of spending extra time in short IRQ handlers doing accounting for time. The former problem can be avoided by using a fixed clock as a timesource, e.g. rdtsc on modern x86 systems which ticks at constant frequency regardless of actual CPU speed. But that reference frequency varies by CPU model. Modern Linux uses rdtsc for extra precision between timer int ticks.Supervise

© 2022 - 2024 — McMap. All rights reserved.