传统代码可能包含普通计算 DO 循环的源代码重构,其目的是使旧式的向量化编译器生成用于特定体系结构的最佳代码。大多数情况下,这些重构不再需要了,而且可能会降低程序的可移植性。两种常见的重构分别是条状提取和循环展开。
有些体系结构中的固定长度矢量寄存器可让程序员手动将循环中的数组计算条状提取成各个段。
REAL TX(0:63) ... DO IOUTER = 1,NX,64 DO IINNER = 0,63 TX(IINNER) = AX(IOUTER+IINNER) * BX(IOUTER+IINNER)/2. QX(IOUTER+IINNER) = TX(IINNER)**2 END DO END DO |
条状提取对现代编译器已不再适合;可按如下方式编写循环来大大降低模糊程度:
DO IX = 1,N TX = AX(I)*BX(I)/2. QX(I) = TX**2 END DO |
在编译器可用之前手动展开循环是一项典型的源代码优化技巧,它会自动执行此重构。循环被编写为:
DO K = 1, N-5, 6 DO J = 1, N DO I = 1,N A(I,J) = A(I,J) + B(I,K ) * C(K ,J) * + B(I,K+1) * C(K+1,J) * + B(I,K+2) * C(K+2,J) * + B(I,K+3) * C(K+3,J) * + B(I,K+4) * C(K+4,J) * + B(I,K+5) * C(K+5,J) END DO END DO END DO DO KK = K,N DO J =1,N DO I =1,N A(I,J) = A(I,J) + B(I,KK) * C(KK,J) END DO END DO END DO |
应按其原始意图进行改写:
DO K = 1,N DO J = 1,N DO I = 1,N A(I,J) = A(I,J) + B(I,K) * C(K,J) END DO END DO END DO |