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在程序中被覆盖?
答案 0 :(得分:5)
第三种情况下b
存在竞争条件:多个线程在没有正确同步/私有化的情况下读取和写入相同的变量。
请注意,在第二种情况下您没有竞争条件:每个线程都在更新其他人无法访问的某些数据(即c(i)
)。
最后,针对您上一个场景的一些解决方案:
reducion(+:b)
子句添加到pragma pragma omp atomic
表达式b = b + c(j,i)
指令