我编写了以下Fortran代码来测试atomic和critical
program test
implicit none
integer::i
integer::a(10),b(10),atmp(10),btmp(10)
a=[1,2,3,4,5,6,7,8,9,10]
b=[12,32,54,77,32,19,34,1,75,45]
atmp=a
btmp=b
write(*,'(1X,10I4)') a+b
print*,'------------------'
!$omp parallel
!$omp do
do i=1,10
B(I) = B(I)+A(I)
end do
!$omp end do
!$omp single
write(*,'(1X,10I4)') b
!$omp end single
a=atmp
b=btmp
!$omp do
do i=1,10
!$omp critical
B(I) = B(I)+A(I)
!$omp end critical
end do
!$omp end do
!$omp single
write(*,'(1X,10I4)') b
!$omp end single
a=atmp
b=btmp
!$omp do
do i=1,10
!$omp atomic
B(I) = B(I)+A(I)
!$omp end atomic
end do
!$omp end do
!$omp single
write(*,'(1X,10I4)') b
!$omp end single
!$omp end parallel
end program
Run Code Online (Sandbox Code Playgroud)
输出是
这意味着结果atomic和critical错误.这很奇怪,我认为添加它们可以避免比赛条件.但是,没有同步的第一个循环给出正确的答案,这里没有比赛吗?我的代码出了什么问题?
代码中的问题是竞争条件
!$omp parallel
...
a=atmp
b=btmp
...
!$omp end parallel
Run Code Online (Sandbox Code Playgroud)
所有线程都执行该操作并且它们发生冲突.你想要omp single围绕这些线.
你不需要任何atomic或critical在
!$omp do
do i=1,10
B(I) = B(I)+A(I)
end do
!$omp end do
Run Code Online (Sandbox Code Playgroud)
因为每个线程都在不同的数组元素上运行.
在您的OpenMP规范示例中,问题在于
!$OMP PARALLEL DO SHARED(X, Y, INDEX, N)
DO I=1,N
!$OMP ATOMIC UPDATE
X(INDEX(I)) = X(INDEX(I)) + WORK1(I)
Run Code Online (Sandbox Code Playgroud)
数组或函数INDEX(I)可以为两个不同的线程返回相同的值,I并且必须保护这种潜在的竞争条件.
| 归档时间: |
|
| 查看次数: |
634 次 |
| 最近记录: |