fortran中的并行do错误

fortran中的并行do错误,fortran,openmp,Fortran,Openmp,我在上面写了一段Fortran代码来实现OpenMP,以三种不同的方式汇总8*8数组中的所有元素。第一种方法是使用减缩和工作。其次,我创建了一个包含8个元素的一维数组。我将平行区域中的每列求和,然后将它们求和。这同样有效。第三个,我用一个整数把数组中的每个元素求和,并把它放在并行do区域。此结果不正确,每次都会发生变化。我不明白为什么会发生这种情况。是因为没有指定public和private,还是过程中重写了变量b 在第三个场景中,b上有一个争用条件:多个线程在没有正确同步/私有化的情况下读取和

我在上面写了一段Fortran代码来实现OpenMP,以三种不同的方式汇总8*8数组中的所有元素。第一种方法是使用减缩和工作。其次,我创建了一个包含8个元素的一维数组。我将平行区域中的每列求和,然后将它们求和。这同样有效。第三个,我用一个整数把数组中的每个元素求和,并把它放在并行do区域。此结果不正确,每次都会发生变化。我不明白为什么会发生这种情况。是因为没有指定public和private,还是过程中重写了变量b

在第三个场景中,b上有一个争用条件:多个线程在没有正确同步/私有化的情况下读取和写入同一个变量

请注意,在第二个场景中没有竞争条件:每个线程都在更新一些其他人无法访问的数据,例如ci

最后,为您的上一个场景提供一些解决方案:

将reduction+:b子句添加到pragma 在b=b+cj,i表达式之前添加pragma omp原子指令 您可以实现手动私有化
在第三个场景中,b上有一个争用条件:几个线程在没有正确同步/私有化的情况下读取和写入同一个变量

请注意,在第二个场景中没有竞争条件:每个线程都在更新一些其他人无法访问的数据,例如ci

最后,为您的上一个场景提供一些解决方案:

将reduction+:b子句添加到pragma 在b=b+cj,i表达式之前添加pragma omp原子指令 您可以实现手动私有化
您可以通过指定reduce+:b来纠正争用条件。此代码似乎假设有八个线程。如果你在一台更大的机器上运行,那就不是真的!请注意,我不建议您添加numthreads8子句,而是建议任何像这样显式使用线程号的代码都是一个坏主意……是的,我定义了8个线程。我应该提到这一点。您可以通过指定reduce+:b来纠正竞争条件。这段代码似乎假设有八个线程。如果你在一台更大的机器上运行,那就不是真的!请注意,我不建议您添加numthreads8子句,而是建议任何像这样显式使用线程号的代码都是一个坏主意……是的,我定义了8个线程。我应该提到这一点。在上一个循环中,他似乎有同样的问题,所有线程都在读取和更新b。我指的是那一个,另外两个计算A和的并行循环都很好。好吧,只是你提到的b场景是第四个,不是第三种情况:似乎他在上一个循环中也遇到了同样的问题,所有线程都在读取和更新b。我指的是那一个,其他两个计算A和的并行循环都很好。好吧,只是你提到的b情况是第四种,而不是第三种情况:
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