在 C++ OpenMP 代码中测量执行时间
Posted
技术标签:
【中文标题】在 C++ OpenMP 代码中测量执行时间【英文标题】:Measure execution time in C++ OpenMP code 【发布时间】:2022-01-03 19:35:45 【问题描述】:我正在运行 .cpp 代码 (i) 以顺序样式和 (ii) 使用 OpenMP 语句。我正在尝试查看时差。为了计算时间,我用这个:
#include <time.h>
.....
main()
clock_t start, finish;
start = clock();
.
.
.
finish = clock();
processing time = (double(finish-start)/CLOCKS_PER_SEC);
在代码的顺序(以上)运行中时间非常准确。运行它大约需要 8 秒。当我在代码中插入 OpenMP 语句并计算时间时,我会减少时间,但在控制台上显示的时间约为 8-9 秒,而实际上它只是实时的 3-4 秒!
这是我的代码的抽象外观:
#include <time.h>
.....
main()
clock_t start, finish;
start = clock();
.
.
#pragma omp parallel for
for( ... )
for( ... )
for (...)
...;
.
.
finish = clock();
processing time = (double(finish-start)/CLOCKS_PER_SEC);
当我运行上面的代码时,我得到了时间的减少,但显示的时间在实时方面并不准确。在我看来,clock () 函数似乎在计算每个线程的单独时间并将它们加起来并显示它们。
有人能说出原因或建议我使用其他计时功能来测量 OpenMP 程序中的时间吗?
谢谢。
【问题讨论】:
介意设置这个答案:***.com/a/63621357/3785618 是正确答案吗? 8 年后,从技术上讲是最合适的,所以当人们看到这个 (***.com/a/10874375/3785618) 被选中时会感到困惑。 【参考方案1】:您可以在 omp 库本身中使用内置的 omp_get_wtime
函数。下面是一个示例代码 sn-p 找出执行时间。
#include <stdio.h>
#include <omp.h>
int main()
double itime, ftime, exec_time;
itime = omp_get_wtime();
// Required code for which execution time needs to be computed
ftime = omp_get_wtime();
exec_time = ftime - itime;
printf("\n\nTime taken is %f", exec_time);
【讨论】:
这其实是最好的解决方案【参考方案2】:#include "ctime"
std::time_t start, end;
long delta = 0;
start = std::time(NULL);
// do your code here
end = std::time(NULL);
delta = end - start;
// output delta
【讨论】:
【参考方案3】:我看到 clock() 报告 CPU 时间,而不是实时。
你可以使用
struct timeval start, end;
gettimeofday(&start, NULL);
// benchmark code
gettimeofday(&end, NULL);
delta = ((end.tv_sec - start.tv_sec) * 1000000u +
end.tv_usec - start.tv_usec) / 1.e6;
改为计时
【讨论】:
我希望你已经看到了,这是指定行为的一部分。另请注意,(end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec
溢出的可能性要小得多。
@BenVoigt 我对自己出色的错误表现感到谦卑。我对此进行了 CW 编辑,因为我对这个答案不应该得到比我已经得到的更多的赞誉。感谢您纠正(微妙/非微妙)错误。
什么头文件包含这个gettimeofday()
函数?我所拥有的只是time.h
中的mingw_gettimeofday()
(Windows 64中的mingw)
@samadmontazeri Google 的first result 告诉我#include <sys/time.h>
为什么不delta = (end.tv_sec-start.tv_sec)+(end.tv_usec-start.tv_usec)*1e-6
?如果我等了几个小时,(end.tv_sec-start.tv_sec)*1000000u
是否会超过最大值 unsigned int
?【参考方案4】:
在我看来,clock () 函数似乎在计算每个线程的单独时间并将它们加起来并显示它们。
这正是clock()
所做的 - 它测量进程使用的 CPU 时间,至少在 Linux 和 Mac OS X 上意味着所有线程的累积 CPU 时间自启动以来一直在进行中。
OpenMP 应用程序的实时时钟(也称为挂钟)计时应使用高分辨率 OpenMP 计时器调用 omp_get_wtime()
来完成,它返回自过去任意点以来的秒数的 double
值。它是一种便携式功能,例如Unix 和 Windows OpenMP 运行时都存在,不像 gettimeofday()
仅适用于 Unix。
【讨论】:
“进程中的所有线程”......可能会也可能不会。根据文档,还可能包含收获的子进程。 嗯,ISO/IEC 9899:1999 和 SUSv3 均未提及子进程:“clock() 函数应返回自实施开始以来进程使用的处理器时间的最佳近似值——仅与进程调用相关的已定义时代。” 嗯,Linux 手册页说它与其他一些操作系统不兼容(它没有说明哪些操作系统实际上包含子进程)。【参考方案5】:是的,这就是clock()
应该做的,告诉你程序使用了多少处理器时间。
如果要查找经过的实时时间,而不是 CPU 时间,请使用返回挂钟时间的函数,例如 gettimeofday()
。
【讨论】:
以上是关于在 C++ OpenMP 代码中测量执行时间的主要内容,如果未能解决你的问题,请参考以下文章