Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Fortran openmp的编程问题_Fortran_Openmp - Fatal编程技术网

Fortran openmp的编程问题

Fortran openmp的编程问题,fortran,openmp,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 ....

我在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 ...
编译没有问题,但是当我运行程序时,与串行代码的结果相比,有两个主要问题:

  • 该程序的运行速度甚至比串行代码(假定在do循环中执行矩阵乘法(matmul))还要慢
  • 与串行代码相比,数字精度似乎有所下降(我对此进行了检查)
  • 有什么想法吗?
    谢谢,

    Xiaoyu

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

    OMP_NUM_THREADS=5 ./myprogram
    
    使用5个线程执行它

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

    旁注

  • 如果循环中有私有变量,不要忘记设置它们!
    例如:

    !$omp并行do专用(预调)
    i=1,N
    prelimRes=myFunction(i)
    res(i)=prelimRes+someValue
    结束do
    !$omp端平行do

    注意变量
    prelimRes
    是如何声明的
    private
    ,这样每个线程都有自己的工作区

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

  • 如果不确定发生了什么,则应在程序运行时使用
    htop
    或类似程序检查CPU负载
  • 附录:设置线程数以自动匹配CPU数 如果您希望使用最大数量的有用线程,例如使用尽可能多的CPU线程,可以使用(正如您在问题中所述):


    @Rain这确实是可能的。您应该注意
    omp\u get\u num\u procs()
    的结果。好的,如果您希望获得可靠的结果,您应该只在omp环境中使用此命令。@Rain如果我理解正确,您已经设置了进程数(但似乎不起作用)?你检查了我帖子中的另外两个提示了吗?我在主上下文中设置了已修改的进程数,并检查了程序运行时,系统监视器是否显示程序正在使用的4个线程program@Rain我假设您只有4个CPU?以这种方式使用命令的问题是,您从来没有实际分配过numb你的程序有两个线程。我的笔记本电脑上有两个CPU。英特尔有一种超线程技术,可以将它分成四个。我不明白你对我编程问题的答案。是不是do循环没有平均分成四个线程?可能是重复的,或者更好:
    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 ...