clock_gettime() 是否在 MinGW GCC 8.2.0 中正确实施?
Is clock_gettime() correctly implemented in MinGW GCC 8.2.0?
一个偶然的机会,我发现 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;
}
此代码片段在没有 warnings/errors 的情况下编译,并且没有运行时失败(至少没有写入标准输出)。
输出:
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
的 return 值(它可能告诉您这些时钟不是支持)。
首先,您的代码正在查询两个不同的时钟(CLOCK_THREAD_CPUTIME_ID
用于 tstart
,CLOCK_PROCESS_CPUTIME_ID
用于 tend
),因此比较两个值。其次,您只查看由 clock_gettime()
编辑的 struct timespec
return 的 tv_nsec
字段,即使两次查询相同的时钟,您的差异也可能是错误的。此外,您的编译器可能正在优化空的 for
循环,但如果不查看生成的二进制文件就无法说出这一点,但我发现这不太可能,除非您使用 -O1
或 [=19= 进行编译](例如,参见 here,仅使用 -O2
即可消除循环)。
此外,Windows 根本不符合 POSIX,MinGW 只能在某种程度上模仿 clock_gettime()
的行为,所以我不会真的相信它 return精确值。 mingw-w64 looking at the source code 好像没问题,但不知道你用的是不是那个版本。尽管 struct timespec
对象以纳秒分辨率描述时间,但可用分辨率取决于系统,甚至可能大于 1 秒。你可能想看看 clock_getres()
说的是什么。
According to the N1570 Committee draft (April 12, 2011) of the ISO/IEC 9899:201x, shouldn't timespec_get()
take the role of clock_gettime()
instead?
C 标准没有说明任何关于哪个函数应该扮演另一个函数的角色。 timespec_get()
函数确实 而不是 具有与 clock_gettime()
相同的语义。 timespec_get()
函数仅适用于“日历时间”(使用 clock_gettime()
时应与 CLOCK_REALTIME
相同)。
一个偶然的机会,我发现 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;
}
此代码片段在没有 warnings/errors 的情况下编译,并且没有运行时失败(至少没有写入标准输出)。
输出:
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
的 return 值(它可能告诉您这些时钟不是支持)。
首先,您的代码正在查询两个不同的时钟(CLOCK_THREAD_CPUTIME_ID
用于 tstart
,CLOCK_PROCESS_CPUTIME_ID
用于 tend
),因此比较两个值。其次,您只查看由 clock_gettime()
编辑的 struct timespec
return 的 tv_nsec
字段,即使两次查询相同的时钟,您的差异也可能是错误的。此外,您的编译器可能正在优化空的 for
循环,但如果不查看生成的二进制文件就无法说出这一点,但我发现这不太可能,除非您使用 -O1
或 [=19= 进行编译](例如,参见 here,仅使用 -O2
即可消除循环)。
此外,Windows 根本不符合 POSIX,MinGW 只能在某种程度上模仿 clock_gettime()
的行为,所以我不会真的相信它 return精确值。 mingw-w64 looking at the source code 好像没问题,但不知道你用的是不是那个版本。尽管 struct timespec
对象以纳秒分辨率描述时间,但可用分辨率取决于系统,甚至可能大于 1 秒。你可能想看看 clock_getres()
说的是什么。
According to the N1570 Committee draft (April 12, 2011) of the ISO/IEC 9899:201x, shouldn't
timespec_get()
take the role ofclock_gettime()
instead?
C 标准没有说明任何关于哪个函数应该扮演另一个函数的角色。 timespec_get()
函数确实 而不是 具有与 clock_gettime()
相同的语义。 timespec_get()
函数仅适用于“日历时间”(使用 clock_gettime()
时应与 CLOCK_REALTIME
相同)。