【发布时间】:2016-02-18 09:33:52
【问题描述】:
我正在努力并行化一小部分具有循环和调用子例程的代码。但结果与 1 线程或 2 线程不一致。
这种类型的程序是不是必须使用锁?
!$OMP parallel private(kk,j,i,k1,j1,i1,k2,j2,i2,ic,icm,xx,yy,ydatm),shared(undef,lt,ln,nd,xd,tgrd,ndaym)
thread_id = OMP_GET_THREAD_NUM()
num_threads = OMP_GET_NUM_THREADS()
if(thread_id.eq.0) thread_id=thread_id+1
start_no = (thread_id * ndaym / num_threads);
end_no = ((thread_id + 1) * ndaym / num_threads);
xx(:)=undef
yy(:,:)=undef
!$OMP DO
DO kk=start_no,end_no
do j=1,nlat
do i=1,nlon
ic=0
do k1=kk-nd,kk+nd
k2=k1
if(k2.lt.1)k2=1
if(k2.gt.ndaym)k2=ndaym
do j1=j-lt,j+lt
j2=j1
if(j2.lt.1)j2=1
if(j2.gt.nlat)j2=nlat
do i1=i-ln,i+ln
i2=i1
if(i2.lt.1)i2=1
if(i2.gt.nlon)i2=i2-nlon
ic=ic+1
yy(ic,:)=xdatm(i2,j2,k2,:)
yya(:) = yy(ic,:)
call funcmean(yya,xx(ic),1,nmem,nmem,undef)
if(k1.eq.kk.and.j1.eq.j.and.i1.eq.i) then
icm=ic
call funcsd(yya,1,nmem,nmem,undef,xx(ic),xd)
endif
enddo ! for i1
enddo ! for j1
enddo ! for k1
call funcens(xx,yy,tgrd,nmem,icm,undef,dist)
ydatm(i,j,kk,:)= dist(:)
enddo !for nlon
enddo ! for nlat
ENDDO !kk
!$OMP end do
deallocate(xx,yy)
!$OMP end parallel
谁能提供一些线索?
【问题讨论】:
-
在我看来,您好像在尝试计算每个线程在外部 do 循环迭代中所占的份额,而所有这些都在计算
start_no和end_no。如果是这样,您宁愿错过了有关 OpenMP 的要点之一,即编译器会为您执行此操作。网上有很多很好的例子,甚至在 SO 上也有,向您展示 Fortran+OpenMP 中并行化 do 循环的常见上层结构。
标签: multithreading openmp locks