【发布时间】:2015-04-01 07:59:01
【问题描述】:
我有一个 fortran 程序的一部分,其中包含一些我想与 OpenMP 并行化的嵌套循环。
integer :: nstates , N, i, dima, dimb, dimc, a_row, b_row, b_col, c_row, row, col
double complex, dimension(4,4):: mat
double complex, dimension(:), allocatable :: vecin,vecout
nstates = 2
N = 24
allocate(vecin(nstates**N), vecout(nstates**N))
vecin = ...some data
vecout = 0
mat = reshape([...some data...],[4,4])
dimb=nstates**2
!$OMP PARALLEL DO PRIVATE(dima,dimc,row,col,a_row,b_row,c_row,b_col)
do i=1,N-1
dima=nstates**(i-1)
dimc=nstates**(N-i-1)
do a_row = 1, dima
do b_row = 1,dimb
do c_row = 1,dimc
row = ((a_row-1)*dimb + b_row - 1)*dimc + c_row
do b_col = 1,dimb
col = ((a_row-1)*dimb + b_col - 1)*dimc + c_row
!$OMP ATOMIC
vecout(row) = vecout(row) + vecin(col)*mat(b_row,b_col)
end do
end do
end do
end do
end do
!$OMP END PARALLEL DO
程序运行,我得到的结果也是正确的,只是慢得令人难以置信。比没有 OpenMP 慢得多。我对 OpenMP 了解不多。我在使用 PRIVATE 或 OMP ATOMIC 时做错了吗?对于如何提高我的代码性能的每一个建议,我将不胜感激。
【问题讨论】:
-
您应该看一下
vecout的reduction子句。这应该加快速度;-) -
在最内层循环中使用原子指令不是一个好主意!
-
感谢您的回答。为什么原子指令是一个坏主意?我删除了原子指令并改用了 REDUCTION(+:vecout) ,这导致了分段错误。归约和数组有什么特别之处吗?
-
缩减工作仅适用于小型数组而不会出现分段错误。
-
那你需要增加栈大小:
ulimit -s unlimited
标签: parallel-processing fortran openmp