我偶然发现了Linux系统上clock_gettime()
函数的存在。由于我正在寻找一种衡量函数执行时间的方法,因此我在Windows 10 64位计算机上的MinGW gcc 8.2.0版本中进行了尝试:
#include <time.h>
#include <stdio.h>
int main() {
struct timespec tstart, tend;
clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tstart);
for (int i = 0; i < 100000; ++i);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tend);
printf("It takes %li nanoseconds for 100,000 empty iterations.\n", tend.tv_nsec - tstart.tv_nsec);
return 0;
}
该代码段编译时不会发出警告/错误,也没有运行时失败(至少没有写入stdout)。
输出:
It takes 0 nanoseconds for 100,000 empty iterations.
我不相信这是真的。
您能发现缺陷吗?
还有一件事:
根据ISO / IEC 9899:201x的N1570 Committee draft(2011年4月12日),timespec_get()
是否应该代替clock_gettime()
的角色?
答案 0 :(得分:2)
该循环应该完全没有优化,因此使用低分辨率时钟(分辨率不一定是单个纳秒;它可以以更大的单位前进,clock_getres
应该可以告诉您)0是一个合理的结果。但是您的代码中还有一些其他错误,例如将CLOCK_THREAD_CPUTIME_ID
与CLOCK_PROCESS_CPUTIME_ID
混合在一起,而不检查clock_gettime
的返回值(这可能表明您不支持这些时钟)。 / p>
答案 1 :(得分:2)
首先,您的代码正在查询两个不同的时钟(CLOCK_THREAD_CPUTIME_ID
的{{1}}和tstart
的{{1}}),因此比较这两个值没有任何意义。其次,您仅查看CLOCK_PROCESS_CPUTIME_ID
返回的tend
的{{1}}字段,即使两次查询相同的时钟,您的差异也可能是错误的。另外,您的编译器可能正在优化空的tv_nsec
循环,但是如果不查看生成的二进制文件就无法说这句话,但是除非您使用struct timespec
或{{1}进行编译,否则我发现这不太可能}(例如,参见here,仅用clock_gettime()
消除了循环)。
此外,Windows根本不兼容POSIX,MinGW只能在某种程度上模拟for
的行为,因此我真的不相信它能返回精确的值。对于mingw-w64 looking at the source code来说似乎还可以,但是我不知道那是您使用的版本。即使-O1
对象以纳秒分辨率描述时间,可用分辨率也取决于系统,甚至可能大于1秒。您可能要检查-O2
的内容。
根据ISO / IEC 9899:201x的N1570 Committee draft(2011年4月12日),
-O2
是否应该代替clock_gettime()
的角色?
C标准对任何功能应扮演其他角色一无所知。 struct timespec
函数肯定不具有与clock_getres()
相同的语义。 timespec_get()
函数仅在“日历时间”上起作用(使用clock_gettime()
时,该时间应与timespec_get()
相同)。