真实的CPU频率与C语言中的clock_t之间有什么关系?

6

在C语言中,真实的CPU频率和clock_t(单位为时钟滴答)之间有什么关系呢?

假设我有以下一段C代码,它用于测量CPU运行for循环所消耗的时间。
但由于标准库中的CLOCKS_PER_SEC是一个常数值(基本上是1000,000),因此我想知道clock函数如何测量程序在不同计算机上运行时消耗的真实CPU周期(对于我的笔记本电脑,它是2.6GHz)。

如果它们并不相关,那么在所提到的场景中,CPU定时器是如何工作的呢?

#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;
}

1
它与电流比率有关吗?定时由固定源提供,例如振荡器电路。由于大多数现代CPU具有动态频率,因此基于CPU频率的可靠定时是不可能的。 - user2864740
1
你为什么认为测量/了解/使用CPU周期是必要的呢?为了提供经过的时间,只需要测量时间即可。读取硬件计时器是一种方法。请注意,即使您知道所使用的CPU周期,由于流水线、并行性、中断、分支预测等因素的存在,从该信息计算经过的时间现在几乎是不可能的。 - Yunnosch
CLOCKS_PER_SEC 只是给出 clock() 返回值的 计量单位。它并不是 "基本上是 1000,000",而是由操作系统/编译器决定应该是什么。例如,在我的系统上它是 1000。这就是为什么它在计时目的上是一个相当粗糙的工具的原因之一 - 它的粒度会因系统而异。 - Weather Vane
我认为我们可能正在看 https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem 请考虑您是否真的想讨论clock()如何工作,或者您是否确实想知道如何测量当前程序所花费的CPU时钟周期。或者也许您想知道如何在多线程(可能是多CPU)环境中测量当前程序所花费的时间。这些都是不同的问题,您应该提出您想要回答的问题,而不是迷失在您认为会给您答案的细节中。 - Yunnosch
然而,如果您实际上想要回答不同的问题而不是在此处提出的问题,请保留此问题(及其得到赞同的答案),并创建一个单独的新问题帖子。而不是从根本上改变这个问题,从而使答案无效。 - Yunnosch
@Yunnosch 我开了另一个问题:https://dev59.com/asPra4cB1Zd3GeqPc0oV?noredirect=1#comment124875121_70639995 - Jason Yu
3个回答

7

实际上,clock_t值与CPU频率无关。

详细解释请见此处

虽然理论上来说,clock_t类型的值可以表示实际物理CPU时钟周期,但在实践中却不是这样的:POSIX规定 CLOCKS_PER_SEC 等于100万-一百万。因此,clock_t函数返回一个微秒级别的值。


对于在一个系统上编译的二进制文件能够在另一个系统上运行,有必要使用一些固定常量。即使在固定CPU频率的时代,同一架构的不同系统可能具有不同的核心时钟频率。而且,这是一个软件时钟,由计时器中断递增或在上下文切换时计算,而不是直接从核心时钟周期派生的正常实现。 - Peter Cordes

3

在任何人的笔记本电脑上,都不存在“真正的CPU频率”。

在许多系统中,操作系统可以根据需要降低和提高CPU时钟速度。在某些系统中,有多种类型的中央处理器或核心,每个核心速度不同。有些CPU是“无时钟”(异步的)。

因为以上这些原因和其他原因,大多数计算机使用单独的时钟设备来测量时间,该设备独立于CPU时钟(如果有的话)。


1
为了提供所示代码中使用的信息,测量/了解/使用CPU周期并不相关。
为了提供经过的时间,只需要测量时间即可。读取硬件计时器是一种方法。大多数计算机(甚至非嵌入式计算机)都包含定时器,这些定时器特别计算具有已知恒定频率的时钟的滴答声。 (它们特别不是“CPU计时器”。)这样的计时器可以被读取,并产生一个值,该值每个滴答声(具有恒定周期)增加一次。其中“已知周期”是指某个适当的驱动程序对该计时器的周期进行了了解,简化的说“已知于clock()函数,而不一定为您所知”。
请注意,即使已知使用的CPU周期数量,由此计算出经过的时间在当前情况下几乎是不可能的,因为存在以下情况:
- 管道 - 并行性 - 中断 - 分支预测
还有其他影响/防止计算的事项,来自评论贡献:
- 频率调节、温度限制和电源设置(David C. Rankin)

:-) 我想你不介意我使用它来扩展列表。谢谢。@DavidC.Rankin - Yunnosch
有趣的是,您也没有提到“缓存”。我故意这样做,因为虽然它们通常会影响CPU周期的数量和结果持续时间,但它们不会影响比率周期/时间。我猜您也是这样想的。 - Yunnosch
时钟怎么知道CPU何时调度运行当前程序?我认为它不会——那是一个特性。在多线程程序中,返回的值会高于挂钟时间。你的理解和我的不同。如果时钟只能在CPU处理给定程序时测量时间,那么测量的时间将比挂钟短而不是长。即使我的理解是错误的。你的表述似乎不一致。 - Yunnosch
@Yunnosch 你说得对,这样会更简短。我的错误。 - Jason Yu
我基本上遵循“挂钟时间”。你不必相信我。但你应该澄清你想讨论什么,看看我的问题评论。然后其他人可以给出一个立即对你有帮助的答案。他们可能会与我相矛盾,我也能学到一些东西... - Yunnosch
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接