【问题标题】:Measure execution time in C++ OpenMP code在 C++ OpenMP 代码中测量执行时间
【发布时间】: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 程序中的时间吗?

谢谢。

【问题讨论】:

标签: c++ time parallel-processing openmp


【解决方案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()

    【讨论】:

      猜你喜欢
      • 2013-04-28
      • 2013-06-24
      • 1970-01-01
      • 2011-04-23
      • 2017-02-04
      • 2012-06-19
      • 1970-01-01
      • 2021-08-10
      相关资源
      最近更新 更多