在 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 &lt;sys/time.h&gt; 为什么不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 代码中测量执行时间的主要内容,如果未能解决你的问题,请参考以下文章

在多线程 C++ 应用程序中测量时间

OpenMP C++ 中的线程

c#/wpf OpenMP 在外部 dll 中

Visual C++ 只有一个线程工作 (OpenMP)

不同线程号openMP上的相同程序执行时间

在 Openmp (C++) 中销毁线程