我很难理解处理器时间。该计划的结果:
#include <iostream>
#include <chrono>
// the function f() does some time-consuming work
void f()
{
volatile long double d;
int size = 10000;
for(int n=0; n<size; ++n)
for(int m=0; m<size; ++m)
d = n*m;
}
int main()
{
std::clock_t start = std::clock();
f();
std::clock_t end = std::clock();
std::cout << "CPU time used: "
<< (end - start)
<< "\n";
}
似乎在210 000,220 000和230 000之间随机波动。起初我很惊讶,为什么这些离散值。然后我发现std::clock()
仅返回approximate processor time。因此,std::clock()
返回的值可能会舍入到10 000的倍数。这也可以解释为什么CPU时间之间的最大差异为20 000(10 000 ==第一次调用{{1时的舍入误差第二个和10 000个。)
但是如果我在std::clock()
的身体中改为int size = 40000;
,我会在3 400 000到3 500 000的范围内出现波动,这无法用四舍五入来解释。
根据我在维基百科上看到的clock rate:
CPU需要固定数量的时钟周期(或时钟周期) 执行每条指令。时钟越快,指令越多 CPU可以每秒执行一次。
也就是说,如果程序是确定性的(我希望是我的),那么完成所需的CPU时间应该是:
我的实验也没有显示,因为我的程序需要执行至少f()
条指令。你能解释一下我做错了吗?
答案 0 :(得分:7)
首先,您从维基百科中引用的陈述完全是假的。 20年前可能是真的(但并非总是如此) 然后),但今天完全是假的。有很多事情 这会影响你的时间:
第一个:如果您在Windows上运行,clock
已损坏,
并且完全不可靠。它返回经过的差异
时间,而不是CPU时间。经过的时间取决于各种各样的
处理器可能正在做的其他事情。
除此之外:缓存未命中等问题非常重要 对时间的影响。并且是否有特定的数据 是否缓存取决于您的程序是否 在最后一次访问和此访问之间中断。
一般来说,任何低于10%的东西都很容易归因于 缓存问题。而且我已经看到了10倍的差异 在Windows下,取决于是否正在运行构建或 不
答案 1 :(得分:3)
您没有说明您正在运行二进制文件的硬件。
是否有中断驱动的CPU?
它是一个多任务操作系统吗?
你错误地将CPU的周期时间(维基百科所指的CPU时钟)与从头到尾执行特定代码所需的时间以及可怜的CPU必须做的所有其他事情搞错了同时。
另外......是你在1级缓存中执行的所有代码,或者是2级或主内存中的某些代码,还是磁盘上的代码...下次运行它时会怎么样?
答案 2 :(得分:2)
您的程序不具有确定性,因为它使用了不确定的库和系统函数。
作为一个特例,当您分配内存时,这是虚拟内存,必须映射到物理内存。虽然这是一个系统调用,运行内核代码,但它会在您的线程上进行,并将计入您的时钟时间。执行此操作所需的时间取决于总体内存分配情况。
答案 3 :(得分:1)
对于给定的一组环境,CPU时间确实是“固定的”。但是,在现代计算机中,系统中还会发生其他事情,这会干扰代码的执行。当您的电子邮件软件醒来检查是否有新的电子邮件,或HP打印机软件检查更新时,或者当防病毒软件决定运行以进行一些检查时,可能会消除缓存你的记忆包含任何病毒等等,等等。
部分原因还在于任何系统中的CPU时间记帐不是100%准确的问题 - 它适用于“时钟滴答”和类似的事情,因此例如中断用于服务网络的时间进入的数据包,或硬盘服务中断,或定时器中断说“另一个毫秒勾选”这些全部帐户进入“当前正在运行的进程”。假设这是Windows,还有一个“功能”,即由于历史和其他原因,std::clock()
只是返回现在的时间,而不是实际上是您的进程使用的时间。所以例如:
t = clock();
cin >> x;
t = clock() - t;
如果输入t
的值需要十秒钟,将使x
的时间为10秒,即使这些十秒中的9.999花费在空闲进程中,而不是您的程序。