Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
255 views
in Technique[技术] by (71.8m points)

parallel processing - Issue with OpenMP thread execution and threadprivate variable

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

enter image description here

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Looking at just the first few lines you have major problems.

   do nb=m3+1, m3a, 2

This part is fine, each thread will have a private copy of nb properly initialized.

60   icall=nb

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))    

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)

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 

The variable dflag has not been initialized at this point.

To fix these problems you need to declare icall and iad as private with

!$omp parallel do private(icall,iad)

You should also initialize dflag before you use it.

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...