如何测量在 Fortran OpenMP 线程中执行代码的处理器的运行时间

How to measure elapsed time on a processor executing code in a Fortran OpenMP thread

我使用了 cpu_time,但显然这给出了所有线程的总时间。我使用了 omp_get_wtime,但是得到了一个不正确的负片输出,还有 mpi_wtime,我现在得到了一个核心转储(而之前我得到的只是 0.000000000)。相关代码如下:

      real*8 tbeg, tend
      ....
      !$omp sections private (ie, tbeg, tend)
          !$omp section
              tbeg = omp_get_wtime()
              do ie=1, E
                  call rmul(u, A, B, dudr, duds, dudt, ie)
              enddo
              tend = omp_get_wtime()
              !Step 4: Print results
              print *, tend-tbeg
          !$omp end section
          !$omp section
          ....
          !$omp end section
      !$omp  end sections

我的编译选项是:

gfortran -Ofast -c mult.f -o mult.o -mcmodel=large -I/usr/lib/openmpi/include -fopenmp
gfortran -o baseline ../lib/performance_test.o mult.o ../lib/rose.o -lcuda -lcudart -L/usr/local/cuda-5.0/lib64 -lcublas -lgomp -lmpi_f77

我终于成功地重现了您的问题(虽然有些困难,但我已经解决了)。而且我很确定底线是您在代码中忘记了两件事:

  1. 包含 OpenMP header include 'omp_lib.h' 或更好的 OpenMP 模块 use omp_lib
  2. 禁止隐式变量声明implicit none

虽然后者严格来说不是错误,但它绝对是一个好习惯,它会让你免于前者带来的实际问题,因为你会从编译器那里得到以下信息:

tbeg = omp_get_wtime()
      1 Error: Function 'omp_get_wtime' at (1) has no IMPLICIT type

所以发生的事情是你隐式声明 omp_get_wtime 作为一个函数 returning 一个单精度浮点变量,而它实际上 return 是一个双精度变量。所以 return 值被截断了,你得到的是垃圾。

只需添加正确的 header 并使用代码段中的 omp_get_wtime(),一切都应该是 all-right.