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 带索引条件的两个do循环的OpenMP并行化_Fortran_Openmp_Nested Loops - Fatal编程技术网

Fortran 带索引条件的两个do循环的OpenMP并行化

Fortran 带索引条件的两个do循环的OpenMP并行化,fortran,openmp,nested-loops,Fortran,Openmp,Nested Loops,我已经尝试过并行化包含这样一个双do循环的代码。当然效率不高,但现在这不是什么大问题。 输出tauv为NaN。这是第一个问题 第二个问题是,“英特尔编译器”给出了一个致命错误,线程数小于最大线程数(对于我的机器等于8) 我该如何处理这些问题 !$omp parallel do private(i,j, ro11,ro21,ro12,ro22, &

我已经尝试过并行化包含这样一个双do循环的代码。当然效率不高,但现在这不是什么大问题。 输出tauv为NaN。这是第一个问题

第二个问题是,“英特尔编译器”给出了一个致命错误,线程数小于最大线程数(对于我的机器等于8)

我该如何处理这些问题

            !$omp parallel do   private(i,j,    ro11,ro21,ro12,ro22,        &
                                                u11,u21,u12,u22,            &
                                                v11,v21,v12,v22,            &
                                                es11,es21,es12,es22,        &
                                                p11,p21,p12,p22,            &
                                                te11,te21,te12,te22,        &
                                                emu11,emu21,emu12,emu22)    &
                            shared(i1l, i2l, j1l, j2l, emumax, tauv, tauvij, ro, u, v, es) 
            do i=i1l+2,i2l-2,2
                do j=j1l+2,j2l-2,2
                    if (i.le.niii.and.i.ge.0.and.j.ge.0.and.j.le.nj.or.&
                        i.le.ni.and.i.ge.niik.and.j.gt.njjv.and.j.le.nj.or.&
                        i.le.ni.and.i.ge.niik.and.j.ge.0.and.j.lt.njjn&
                        .or.i.gt.niii.and.i.lt.niik.and.j.gt.njj0+i-niii&
                        .or.i.gt.niii.and.i.lt.niik.and.j.lt.njj0-i+niii) then
                    ro11=ro(i-1,j-1)
                    ro21=ro(i+1,j-1)
                    ro12=ro(i-1,j+1)
                    ro22=ro(i+1,j+1)
                    u11=u(i-1,j-1)
                    u21=u(i+1,j-1)
                    u12=u(i-1,j+1)
                    u22=u(i+1,j+1)
                    v11=v(i-1,j-1)
                    v21=v(i+1,j-1)
                    v12=v(i-1,j+1)
                    v22=v(i+1,j+1)
                    es11=es(i-1,j-1)
                    es21=es(i+1,j-1)
                    es12=es(i-1,j+1)
                    es22=es(i+1,j+1)
                    p11=(es11-0.5*ro11*(u11*u11+v11*v11))*ga1
                    p21=(es21-0.5*ro21*(u21*u21+v21*v21))*ga1
                    p12=(es12-0.5*ro12*(u12*u12+v12*v12))*ga1
                    p22=(es22-0.5*ro22*(u22*u22+v22*v22))*ga1
                    te11=p11/ro11   
                    te21=p21/ro21
                    te12=p12/ro12
                    te22=p22/ro22
                    emu11=te11**1.5*(1.0+s1)/(te11+s1)
                    emu21=te21**1.5*(1.0+s1)/(te21+s1)
                    emu12=te12**1.5*(1.0+s1)/(te12+s1)
                    emu22=te22**1.5*(1.0+s1)/(te22+s1)
                    emumax=emu11
                    if (emu21.gt.emumax) then
                        emumax=emu21
                    end if
                    if (emu12.gt.emumax) then
                        emumax=emu12
                    end if
                    if (emu22.gt.emumax) then
                        emumax=emu22
                    end if
                    tauvij=re*flkv*hx*hx/emumax
                    if (tauvij .le. tauv) then
                        tauv=tauvij
                    endif
                endif
                enddo
            enddo
            !$omp end parallel do
问题是它执行时没有错误,但OpenMP do循环的计算速度比顺序循环慢

从您的:

1.)您的代码在OpenMP区域中仅使用1个线程(?):

  ! Set number of threads
  nthreads = 1
  call omp_set_num_threads(nthreads)
  print *, 'The number of threads are used is ', omp_get_max_threads ( )
我会避免调用omp\u set\u num\u threads()。相反,使用环境变量OMP_NUM_threads指定线程数。对于unix计算机:
export OMP\u NUM\u THREADS=

2.)在“可复制”示例中,并行化循环(第312行)缺少私有/共享声明?根据您在上面写的内容,修复到:

!$omp parallel do default(private) shared(i1l, i2l, j1l, j2l, emumax, tauv, tauvij, ro, u, v, es)
根据以上所有内容,我使用GNU Fortran编译器从我的机器(4c/4t)得到的结果是:

...
Executed time in SEQ code is   60.2720146    
...
Executed time in OMP code is   27.1342430 

欢迎,所有Fortran问题都使用tag。您的代码示例应该包含所有变量的声明,并且是可编译和可测试的。请务必阅读。请给出这样一个完整的例子和完整的代码输出,包括所有的错误信息。@VladimirF,最简单的例子是。问题是它执行时没有错误,但OpenMP do循环的计算速度比顺序循环慢。最简单的例子应该在问题本身中,而不是在注释中的链接中。请理解这不是调试服务,因此请尝试做一些努力。减少代码可能会删除不必要的内容,但仍会保留问题。“您使用的是英特尔Fortran编译器集环境变量OMP_NUM_THREADS。”为什么使用英特尔Fortran?这是标准的OpenMP方式。我从不使用
omp\u set\u num\u线程
。我同意你的看法。在GNU Fortran
OMP_get_max_threads()
中,即使未设置OMP_NUM_threads,也会返回最大线程数。emumax上还有一个争用条件,应使用reductio和tauv来处理。(也考虑如果EMUMAX在更新后,但在TaviVJ计算之前发生了什么,这是合理的吗?)