openmp的编程问题

时间:2014-08-29 18:29:31

标签: fortran openmp

我遇到openmp问题,描述如下:

我有这样的序列号

subroutine ...  
  ...  
  do i=1,N
    ....  
  end do  
end subroutine ...

,openmp代码是

subroutine ...  
  use omp_lib  
  ...  
  call omp_set_num_threads(omp_get_num_procs())
  !$omp parallel do  
  do i=1,N
    ....  
  end do  
  !$omp end parallel do  
end subroutine ...

编译没有问题,但是当我运行程序时,与串行代码的结果相比有两个主要问题:

  1. 程序运行速度比串行代码慢(据说在do-loop中进行矩阵乘法(matmul)
  2. 与序列代码相比,数值准确性似乎有所下降(我有一个检查)
  3. 有什么想法可能会发生什么? 谢谢,
    小予

1 个答案:

答案 0 :(得分:1)

如果使用OpenMP进行并行化,则需要指定程序要使用的线程数。您可以使用环境变量OMP_NUM_THREADS来完成此操作,例如通过

调用您的程序
OMP_NUM_THREADS=5 ./myprogram

使用5个线程执行它。

或者,您可以在运行时设置线程数omp_set_num_threadsdocumentation)。

附注

  1. 如果循环中有任何变量,请不要忘记设置私有变量!
    例如:

      

    !$ omp parallel do private(prelimRes)
      我i = 1,N
        prelimRes = myFunction(i)
        res(i)= prelimRes + someValue
      结束了   !$ omp end parallel do

    请注意变量prelimRes如何声明为private,以便每个线程都有自己的工作空间。

  2. 根据您在循环中实际执行的操作(即使用OpenBLAS),由于不同的parellel处理,您的结果可能确实变化(变化应该小于1e-8关于双精度变量)。

  3. 如果您不确定发生了什么,应该在程序运行时使用htop或类似程序检查CPU负载。
  4. 附录:设置自动匹配CPU数量的线程数 如果您想使用最大数量的有用线程,例如使用与CPU一样多的线程,你可以使用(就像你在问题中所说的那样):

    subroutine ...  
        use omp_lib  
        ...  
        call omp_set_num_threads(omp_get_num_procs())
        !$omp parallel do
        do i=1,N
            ....  
        end do  
        !$omp end do  
        !$omp end parallel
    end subroutine ...