我想在下面对这个代码进行矢量化(仅用于示例),只是假设我应该在数组中编写一个数组。
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
,我得到的信息是只有第一个循环才能成功进行矢量化。
你知道我怎么能把它矢量化吗?或者根本不能进行矢量化?
答案 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)顺序......