为什么 C clock() 返回 0
- 2024-11-11 08:27:00
- admin 原创
- 20
问题描述:
我有类似这样的事情:
clock_t start, end;
start=clock();
something_else();
end=clock();
printf("
Clock cycles are: %d - %d
",start,end);
我总是得到输出“时钟周期为:0 - 0”
知道为什么会发生这种情况吗?
(仅提供一些细节,something_else()函数使用蒙哥马利表示法执行从左到右的幂运算,而且我不能确定 something_else()函数是否确实花费了一些不可忽略的时间。)
这是在 Linux 上。uname -a 的结果是:
Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux
解决方案 1:
clock
该函数不测量CPU时钟周期。
C 表示clock
“返回自仅与程序调用相关的实现定义时代开始以来程序使用的处理器时间的最佳近似值。”
如果您程序的两个连续clock
调用之间所花费的时间少于该clock
函数的一个单位,那么您可以获得0
。
POSIXclock
将单位定义为CLOCKS_PER_SEC
1000000(单位为 1 微秒)。
http://pubs.opengroup.org/onlinepubs/009604499/functions/clock.html
要测量 x86/x64 中的时钟周期,您可以使用内联汇编来检索 CPU 时间戳计数器寄存器的时钟计数rdtsc
。
解决方案 2:
我猜原因是你something_else()
消耗的时间太少,超过了的精度clock()
。我尝试clock()
两次调用,结果和start
都是end
零,但当我在中间做一些耗时的事情时,结果是合理的。
这是我的测试代码片段:
int main(void) {
clock_t start, end;
start = clock();
int c;
for (int i = 0; i < 100; i++) {
for (int j = 0; j < (1<<30); j++) {
c++;
}
}
end = clock();
printf("start = %d, end = %d
", start, end);
return 0;
}
我的电脑上的结果是:
start = 0, end = 27700000
另外,还有两个建议:
测试时,不要使用任何编译器优化。你可能认为你的
something_else()
优化很耗时,但编译器可能会忽略这些操作(尤其是循环),因为它认为它们毫无意义。在您的平台上使用
sizeof(clock_t)
来查看的大小clock_t
。
解决方案 3:
那么,你希望something_else()
花费这些时间吗?试试这个:
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
int main(void) {
struct timeval start, end;
long mtime, secs, usecs;
gettimeofday(&start, NULL);
something_else();
gettimeofday(&end, NULL);
secs = end.tv_sec - start.tv_sec;
usecs = end.tv_usec - start.tv_usec;
mtime = ((secs) * 1000 + usecs/1000.0) + 0.5;
printf("Elapsed time: %ld millisecs
", mtime);
return 0;
}
解决方案 4:
使用clock()来测量时间的正确方法是:
printf("
Time elapsed: %.2f
",1.0*(end-start)/CLOCKS_PER_SEC);
这是因为 clock_t 不能保证是 int,或者任何其他类型。
解决方案 5:
CLOCKS_PER_SEC
检查中的值time.h/clock.h
。例如,在我的系统上(Windows 7 上的 Dev Cpp),它仅仅是1000
。因此,就我的程序而言,每秒有 1000 个滴答声。您的程序something_else
将在几微秒内执行。因此,在clock()
函数调用之前和之后都返回零。
在我的系统上,当我something_else
用像这样的耗时程序替换你的程序时
for (unsigned i=0xFFFFFFFF;i--;);
start=clock();
for (unsigned i=0xFFFFFFFF;i--;);
end=clock();
我明白了
时钟周期为:10236 - 20593
在其中一个 Linux 机器上,我发现以下内容bits/time.h
/* ISO/IEC 9899:1990 7.12.1: <time.h>
The macro `CLOCKS_PER_SEC' is the number per second of the value
returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
The value of CLOCKS_PER_SEC is required to be 1 million on all
XSI-conformant systems. */
# define CLOCKS_PER_SEC 1000000l
因此,在分析返回值之前,请考虑这一点clock()
解决方案 6:
我使用了下面的小程序来调查挂钟时间和 CPU 时间。
在我的测试系统上打印
CLOCKS_PER_SEC 1000000
CPU time usage resolutio
看起来0.010000 seconds
gettimeofday 已更改9634 uS
CPU 时间已更改0.010000
gettimeofday 分辨率看起来是 1 us
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <ctime>
int main(int argc, char** argv) {
struct timeval now; // wall clock times
struct timeval later;
clock_t tNow = clock(); // clock measures CPU time of this Linux thread
gettimeofday(&now, NULL); // wall clock time when CPU time first read
clock_t tLater = tNow;
while (tNow == tLater)
tLater = clock(); // consume CPU time
gettimeofday(&later, NULL); // wall clock time when CPU time has ticked
printf("CLOCKS_PER_SEC %ld
",CLOCKS_PER_SEC);
double cpuRes = (double)(tLater - tNow)/CLOCKS_PER_SEC;
printf("CPU time usage resolution looks to be %f seconds
", cpuRes);
unsigned long long nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
nowUs += (unsigned long long)now.tv_usec;
unsigned long long laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
laterUs += (unsigned long long)later.tv_usec;
printf("gettimeofday changed by %d uS when CPU time changed by %f seconds
", (int)(laterUs - nowUs), cpuRes);
// now measure resolution of gettimeofday
gettimeofday(&now, NULL);
later = now;
while ((now.tv_sec == later.tv_sec) && (now.tv_usec == later.tv_usec))
gettimeofday(&later, NULL);
nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
nowUs += (unsigned long long)now.tv_usec;
laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
laterUs += (unsigned long long)later.tv_usec;
printf("gettimeofday resolution looks to be %d us
", (int)(laterUs - nowUs));
}
解决方案 7:
我在使用 C++ 和 g++ 编译器的 Red Hat Linux 上尝试使用向量计算通用类和非通用类之间的差异时遇到了同样的问题。似乎如果您的程序运行速度比单个时钟慢,则 clock() 读数将始终为零 (0)。
此代码将始终返回 0
#include <iostream>
#include <ctime>
using namespace std;
int main() {
cout << clock() << endl;
return 0;
}
当我添加一个索引高达一千万的 for 循环来减慢程序速度时,我得到了一个数字 20000 作为 clock() 的结果
#include <iostream>
#include <ctime>
using namespace std;
int main() {
for (int i = 0; i < 10000000; i++) {}
cout << clock() << endl;
return 0;
}
当然,根据您的盒子的统计数据,结果会有所不同,我正在使用多处理器 Xeon CPU 以及大量 RAM 运行此代码。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件