OpenMP线程执行和threadprivate变量问题 [英] Issue with OpenMP thread execution and threadprivate variable
问题描述
我已经将8个线程用于8个循环.我已经使用打印"来查看并行代码的工作方式. 0线程会产生问题!我在附图中(请检查下面的链接)显示了并行工作的方式.我使用过threadprivate,但事实证明,线程0无法获得任何私有线程安全变量.
I have used 8 threads for 8 loops. I have used 'print' to see how the parallel code works. The 0 thread creates problems!I have showed in the attached diagram (please check the attached link below) how the parallel works. I have used threadprivate but it turned out that thread 0 can not get any private threadsafe variables.
我也尝试过使用模块,并且得到了相同的结果! 知道为什么代码以这种方式工作吗?我将不胜感激任何帮助或建议.谢谢!
I have tried with modules as well and got same results! Any idea why the code acts this way? I would appreciate any help or suggestion. Thanks!
!$OMP PARALLEL DO
do nb=m3+1, m3a, 2
60 icall=nb
65 iad=idint(a(icall))
if(iad.eq.0) goto 100
call ford(a(iad),servo)
if(.not.dflag) goto 80
atemp=dble(nemc)
nemc=iad
a(icall)=a(iad+6)
a(iad+6) = atemp
dflag=.false.
goto 65
80 icall=iad+6
goto 65
100 continue
end do
!$OMP END PARALLEL DO
subroutine FORD(i,j)
dimension zl(3),zg(3)
common /ellip/ b1,c1,f1,g1,h1,d1,
. b2,c2,f2,g2,h2,p2,q2,r2,d2
common /root/ root1,root2
!$OMP threadprivate (/ellip/,/root/)
CALL CONDACT(genflg,lapflg)
return
end subroutine
SUBROUTINE CONDACT(genflg,lapflg)
common /ellip/ b1,c1,f1,g1,h1,d1,b2,c2,f2,g2,h2,p2,q2,r2,d2
!$OMP threadprivate (/ellip/)
RETURN
END
推荐答案
仅看头几行,您就会遇到重大问题.
Looking at just the first few lines you have major problems.
do nb=m3+1, m3a, 2
这部分很好,每个线程都有一个正确初始化的nb
的专用副本.
This part is fine, each thread will have a private copy of nb
properly initialized.
60 icall=nb
这是一个问题. icall
是共享的,每个线程都会将其nb
的私有值写入共享中.线程是同时运行的,并且顺序和计时是不确定的,因此无法提前知道每个线程中的icall
值.
This is a problem. icall
is shared and each thread will write its private value of nb
into the shared. Threads run concurrently and the order and timing is non-determanistic so the value of icall
in each thread cannot be known ahead of time.
65 iad=idint(a(icall))
现在,我们使用icall
来计算要存储在共享变量iad
中的值.有什么问题?如果另一个线程在该线程的执行之间写入了icall
的值,则该值可能与上一行不同.每个线程都会破坏iad
的值.
Now we use icall
to calculate a value to store in the shared variable iad
. What are the problems? The value of icall
may not be the same as in the previous line if another thread wrote to it between this thread's execution. The value of iad
is being clobbered by each thread.
if(iad.eq.0) goto 100
call ford(a(iad),servo)
这些行具有与上述相同的问题. iad
的值可能与上面的值不同,并且这两行之间的值可能会不同,这取决于其他线程的执行情况.
These lines have the same problems as above. The value of iad
may not be the same as above and it may not be the same between these two lines depending on the execution of the other threads.
if(.not.dflag) goto 80
此时变量dflag
尚未初始化.
要解决这些问题,您需要将icall
和iad
声明为private with
To fix these problems you need to declare icall
and iad
as private with
!$omp parallel do private(icall,iad)
您还应该在使用dflag
之前对其进行初始化.
You should also initialize dflag
before you use it.
这些最初的错误可能会导致很大一部分问题,但可能无法解决所有问题.您已经设计了非常复杂(难以维护)的线程交互,并且代码中充斥着不良做法(隐式变量,goto
的随意使用),这使该代码难以遵循.
These first errors are probably responsible for a large chunk of your problem but may not fix everything. You have architected very complex (hard to maintain) thread interaction and your code is full of bad practices (implicit variables, liberal use of goto
) which make this code hard to follow.
这篇关于OpenMP线程执行和threadprivate变量问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!