【发布时间】:2015-07-21 09:34:15
【问题描述】:
我想用矢量处理器(英特尔至强)以矢量方式执行 Fortran 循环。我最近用英特尔编译器实现了这一点,我们可以在循环之前添加!DIR$ SIMD。
但是当我使用 gfortran 编译器时,我发现所有的向量化操作都是自动的。例如,
PROGRAM MAIN1
IMPLICIT NONE
DOUBLE PRECISION :: X(100)
INTEGER :: NELEM = 100, NELMAX = 100, LV = 4
INTEGER :: IKLE(100), I, IB, IELEM
DOUBLE PRECISION :: W(100)
DOUBLE PRECISION :: MASKEL(100)
LOGICAL :: MSK = .FALSE.
DO I = 1, 100
X(I) = I
IKLE(I) = I
W(I) = 0
END DO
DO IB = 1,(NELEM+LV-1)/LV
!------------loop to vectorize------------------
DO IELEM = 1+(IB-1)*LV , MIN(NELEM,IB*LV)
X(IKLE(IELEM)) = X(IKLE(IELEM)) + W(IELEM)
ENDDO ! IELEM
!-----------------------------------------------
ENDDO ! IB
PRINT *, X
END PROGRAM
gfortran main1.f -O3 -fopt-info-optimized 的部分输出打印在下面
main1.f:18:0: note: not vectorized: not suitable for gather load _33 = x[_32];
main1.f:18:0: note: bad data references.
main1.f:18:0: note: not vectorized: not enough data-refs in basic block.
main1.f:18:0: note: not vectorized: not enough data-refs in basic block.
由于ifort在强制向量化模式下编译循环时程序输出X是正确的,不知道gfortran是否也有类似的方式。
【问题讨论】:
-
你能摆脱 IKLE(IELEM) 吗?我知道没有这样的 gfortran 指令。您可能需要 OpenMP 4.0 中的 SIMD 指令。我通常不会将英特尔处理器称为“矢量”。
-
是的,我也这样做了,发现它有效。但不幸的是我无法摆脱它,这是计算的一部分。
-
你确定你有使用 ifort 的加速吗?如果你要求它,它甚至会向量化那些无法被向量化的循环。
-
也许不在这个演示中。但它可能在另一个更大的地方有用
-
不清楚向量化是否会加速这个循环:代码的算术强度很低,所以它似乎受内存限制。此外,如果可以的话,在 W 上进行随机读取而不是在 X 上进行随机写入可能是有利可图的。
标签: fortran vectorization gfortran simd