[偶然,我发现了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()
的角色吗?
该循环应该被优化为零,因此使用低分辨率时钟(分辨率不一定是单个纳秒;它可以以更大的单位前进,clock_getres
应该可以告诉您)0是一个合理的结果。但是您的代码中还有一些其他错误,例如将CLOCK_THREAD_CPUTIME_ID
与CLOCK_PROCESS_CPUTIME_ID
混合在一起,并且不检查clock_gettime
的返回值(这可能表明您不支持这些时钟)。
首先,您的代码正在查询两个不同的时钟(CLOCK_THREAD_CPUTIME_ID
的tstart
和CLOCK_PROCESS_CPUTIME_ID
的tend
),因此比较这两个值毫无意义。其次,您只查看tv_nsec
返回的struct timespec
的clock_gettime()
字段,即使两次都查询相同的时钟,您的差异也可能是错误的。同样,您的编译器可能会优化掉空的for
循环,但是如果不查看生成的二进制文件就无法说清楚。
此外,Windows根本不兼容POSIX,MinGW只能在某种程度上模拟clock_gettime()
的行为,因此我真的不相信它会返回精确的值。对于MinGW64 looking at the source code来说似乎还可以,但我不知道您使用的是哪个特定版本。
根据ISO / IEC 9899:201x的N1570 Committee draft(2011年4月12日),
timespec_get()
不应代替clock_gettime()
的角色吗?
C标准没有说任何关于哪个功能应该扮演其他角色。 timespec_get()
函数肯定not的语义与clock_gettime()
相同。 timespec_get(&sp, 0)
仅适用于实时时钟(又称CLOCK_REALTIME
为clock_gettime()
),而不适用于其他时钟,因此您可以使用该时钟(不是)将其替换为另一个if。