并行做错了fortran

时间:2016-08-24 21:40:01

标签: fortran openmp

program main
use omp_lib
implicit none
integer :: n=8
integer :: i, j, myid, a(8, 8), b, c(8)

! Generate a 8*8 array   A                                                                                         
!$omp parallel default(none), private(i, myid), &                                                                
!$omp shared(a, n)                                                                                               
myid = omp_get_thread_num()+1
do i = 1, n
   a(i, myid) = i*myid
end do
!$omp end   parallel                                                                                               

! Array A                                                                                                        
print*, 'Array A is'
do i = 1, n
 print*, a(:, i)
end do

! Sum of array A                                                                                                 
b = 0
!$omp parallel reduction(+:b), shared(a, n), private(i, myid)                                                    
myid = omp_get_thread_num()+1
do i = 1, n
   b = b + a(i, myid)
end do
!$omp end   parallel                                                                                               
print*, 'Sum of array A by reduction is ', b

b = 0
c = 0
!$omp parallel do                                                                                                
do i = 1, n
   do j = 1, n
      c(i) = c(i) + a(j, i)
   end do
end do
!$omp end parallel    do                                                                                            
print*, 'Sum of array A by using parallel do is', sum(c)

!$omp parallel do                                                                                                
do i = 1, n
   do j = 1, n
      b = b + a(j, i)
   end do
end do
!$omp end parallel do                                                                                            
print*, 'Sum of array A by using parallel do in another way is', b

end program main

我在上面写了一段Fortran代码来实现OpenMP,以三种不同的方式总结8 * 8数组中的所有元素。第一个使用减少和工作。其次,我创建了一个包含8个元素的一维数组。我总结了并行区域中的每一列,然后总结它们。这也有效。第三个我使用一个整数来总结数组中的每个元素,并将它并行放入区域。这个结果不正确,每次都会变化。我不明白为什么会出现这种情况。是因为没有指定公共和私有或变量b在程序中被覆盖?

1 个答案:

答案 0 :(得分:5)

第三种情况下b存在竞争条件:多个线程在没有正确同步/私有化的情况下读取和写入相同的变量。

请注意,在第二种情况下您没有竞争条件:每个线程都在更新其他人无法访问的某些数据(即c(i))。

最后,针对您上一个场景的一些解决方案:

  1. reducion(+:b)子句添加到pragma
  2. pragma omp atomic表达式
  3. 之前添加b = b + c(j,i)指令
  4. 您可以实施手动私有化