【发布时间】:2015-08-27 18:48:32
【问题描述】:
我正在使用gfortran 和-mavx 编译我的Fortran 代码,并验证了一些指令是通过objdump 进行矢量化的,但是我没有得到我期望的速度改进,所以我想确保正在对以下参数进行矢量化(这条单条指令占运行时间的约 50%)。
我知道有些指令可以向量化,而有些则不能,所以我想确保可以:
sum(A(i1:i2,ir))
同样,由于我是在一个非常大的矩阵上执行此操作,因此这条单行占用了大约 50% 的运行时间。我可以提供更多关于为什么我这样做的信息,但只要说这是必要的就足够了,尽管我可以在必要时重组内存(例如,我可以将总和作为sum(A(ir,i1:i2))如果可以改为矢量化。
这条线是否被矢量化了?我怎么知道?如果没有被矢量化,如何强制矢量化?
编辑:感谢 cmets,我现在意识到我可以通过 -ftree-vectorizer-verbose 检查此求和的矢量化,并看到这是 not 矢量化。我已将代码重组如下:
tsum = 0.0d0
tn = i2 - i1 + 1
tvec(1:tn) = A(i1:i2, ir)
do ii = 1,tn
tsum = tsum + tvec(ii)
enddo
当我打开-funsafe-math-optimizations 时,这ONLY 会矢量化,但由于矢量化,我确实看到速度又提高了 70%。问题仍然存在:为什么sum(A(i1:i2,ir)) 不矢量化,我怎样才能得到一个简单的sum 来矢量化?
【问题讨论】:
-
Fortran 以列优先方式访问数组,即您当前的版本比
sum(A(ir,i1:i2))快得多。您当前的版本访问了一块连续的内存。 -
关于您的编辑:非常有趣。我本来希望总和被矢量化。您是否使用 sum vs loop 进行了实际基准测试?你玩过优化开关吗?更新:have you tried -ffast-math?
-
OpenMP 4 "simd" 子句和缩减?
-
您也可以尝试
-fopt-info获取更多信息(这在man gcc中有记录)。我猜,有某种形式的循环展开。
标签: fortran sse gfortran simd avx