编译器可以使用由内部数组组成的数组来矢量化循环吗?

时间:2016-08-04 14:57:03

标签: fortran vectorization gfortran

我想在下面对这个代码进行矢量化(仅用于示例),只是假设我应该在数组中编写一个数组。

PROGRAM TEST

  IMPLICIT NONE
  REAL, DIMENSION(2000):: A,B,C  !100000
  INTEGER, DIMENSION(2000):: E
  REAL(KIND=8):: TIME1,TIME2
  INTEGER::I

  DO I=1, 2000       !Actually only this loop could be vectorized
     B(I)=100.00     !by the compiler 
     C(I)=200.00
     E(I)=I  
  END DO

  !Computing computer's running time (start)
  CALL CPU_TIME (TIME1)

  DO I=1, 2000               !This is the problem, somehow I should put
     A(E(I))=B(E(I))*C(E(I)) !an integer array E(I) inside an array 
  END DO                     !I would like to vectorize this loop also, but it didn't work

  PRINT *, 'Results  =', A(2000)
  PRINT *, '   '

  !Computing computer's running time (finish)
  CALL CPU_TIME (TIME2)

  PRINT *, 'Elapsed real time = ', TIME2-TIME1, 'second(s)'

END PROGRAM TEST

我第一次想到,编译器可以理解我想要的东西,不管怎么说都是这样的矢量化:

DO I=1, 2000, 4   !Unrolled 4 times
   A(E(I))=B(E(I))*C(E(I))
   A(E(I+1))=B(E(I+1))*C(E(I+1))
   A(E(I+2))=B(E(I+2))*C(E(I+2))
   A(E(I+3))=B(E(I+3))*C(E(I+3))
END DO

但我错了。我使用了gfortran -Ofast -o -fopt-info-optimized Tes.F95,我得到的信息是只有第一个循环才能成功进行矢量化。

你知道我怎么能把它矢量化吗?或者根本不能进行矢量化?

2 个答案:

答案 0 :(得分:1)

如果E对于不同的I具有相等的值,那么您将多次操纵A的相同元素,在这种情况下,顺序可能很重要。 (虽然不是你的情况。)另外,如果你有多个索引数组,如E1,E2和E3,和

DO I=1, 2000              
   A(E3(I))=B(E1(I))*C(E2(I)) 
END DO

订单也很重要。所以我认为并行循环通常不允许这种索引。

答案 1 :(得分:0)

使用ifort可以使用!DIR $ IVDEP,这是“忽略向量依赖”。它只适用于E(I)是线性的,例如......

假设有人想要完成所有索引,那么只需用(I)替换(E(i))并稍后计算明显的E(I)顺序......