Fortran 有或没有临界值?
关注代码的并行部分,下面给出的选项中哪一个是首选的?有更好的解决办法吗?我试图对Fortran 有或没有临界值?,fortran,openmp,Fortran,Openmp,关注代码的并行部分,下面给出的选项中哪一个是首选的?有更好的解决办法吗?我试图对do\u something 备选方案1:使用关键技术 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 CRITIC
do\u something
备选方案1:使用关键技术
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:避免关键(和原子)
我不能使用reduce(+:resultado%uno)
也不能使用reduce(+:resultado)
在这方面,只允许使用数字类型
IMO认为,这种方法的缺点是必须用线程数对派生的tiperesultadoOmp
进行标注。优点是避免了可能影响性能的关键
子句,对吗
IMO,这种方法的缺点是,必须用线程数对派生的tipe resultadoOmp进行量纲。优点是避免了可能影响性能的关键条款,对吗
是的,你说得对。看起来你是在用线程数标注resultadoOmp的尺寸,所以这不是一个真正的缺点吗?第二部分的性能确实应该更好,尽管两个平行区域可能会再次蚕食这一优势。因此,两个零件应仅使用一个平行区域。根据do_something的运行时间,我甚至可能完全忽略简化操作的并行性,在并行计算所有uno条目后,只需在单个线程上求和:
!$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
do i_omp=1, nthreads
call do_something(large, resultadoOmp(i_omp))
end do
!$OMP END PARALLEL DO
resultado%uno = sum(resultadoOmp(:)%uno)/nthreads
您需要使用实际设置来衡量各种实现,以得出结论。谢谢您的回答!事实上,与do\u something
相比,缩减操作的时间消耗可以忽略不计。正如您所建议的,您可以避免该区域的并行性,而对效率几乎没有影响。
!$OMP PARALLEL DO shared(large) private(i_omp) schedule(static,1)
do i_omp=1, nthreads
call do_something(large, resultadoOmp(i_omp))
end do
!$OMP END PARALLEL DO
resultado%uno = sum(resultadoOmp(:)%uno)/nthreads