着眼于代码的并行部分,下面给出的哪个选项是首选?有更好的解决方案吗?我正在尝试对独立实现进行平均do_something
选项 1:使用 CRITICAL
resultado%uno = 0.d0
!$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
do i_omp=1, nthreads
call do_something(large, resultadoOmp(i_omp))
!$OMP CRITICAL (forceloop)
resultado%uno = resultado%uno + resultadoOmp(i_omp)%uno
!$OMP END CRITICAL (forceloop)
enddo
!$OMP END PARALLEL DO
resultado%uno = resultado%uno/nthreads
选项 2:避免CRITICAL
(和ATOMIC
)
!$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
do i_omp=1, nthreads
call do_something(large, resultadoOmp(i_omp))
enddo
!$OMP END PARALLEL DO
uno = 0.d0
!$OMP PARALLEL DO shared(resultado) private(i_omp) schedule(static,1) &
!$OMP & REDUCTION(+:uno)
do i_omp=1, nthreads
uno = uno + resultadoOmp(i_omp)%uno
end do
!$OMP END PARALLEL DO
resultado%uno = uno/nthreads
在这方面我不能使用,REDUCTION(+:resultado%uno)
也不能使用REDUCTION(+:resultado)
,只允许使用数字类型。
这种方法的缺点,IMO,是必须resultadoOmp
用线程数来确定派生的尖端。好处是避免了CRITICAL
可能影响性能的子句,对吗?