gfortran 编译器的强制向量化

Posted

技术标签:

【中文标题】gfortran 编译器的强制向量化【英文标题】:Mandated vectorization for gfortran compiler 【发布时间】: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 上进行随机写入可能是有利可图的。 【参考方案1】:

在这种分散存储的情况下,当索引数组 IKLE(:) 中有重复条目时,通过指令强制矢量化可能会改变结果,因为它不会保留内存访问的顺序。据我所知,gfortran 中唯一可用的这种性质的指令是 !$omp simd,gfortran 可以随意忽略它。 omp simd 指令仅在设置了相应的编译选项时才有效。 ifort 提供(最新版本中的 -opt-report4)评估可能通过矢量化实现的峰值加速。我不知道该评估是否基于声明的数组大小。如果有加速,那么通过改变操作顺序比通过实际的 SIMD 并行更能实现。

【讨论】:

ifort 和 gfortran 生成的指令序列确实保留了存储的顺序,以防重复。在 avx512 中有冲突解决说明,以备不时之需。

以上是关于gfortran 编译器的强制向量化的主要内容,如果未能解决你的问题,请参考以下文章

Fortran 中的矢量化总和

使用 GCC 强制自动矢量化

除了 gcc 还都有哪些编译器可以向量化代码?

在ubuntu上安装了gfortran编译器,出现了大问题哦!!求助啊!!

配置编译器(GCC和GFortran)

为啥库需要硬编码矢量化而不是编译器自动矢量化