Vereinfachung von Schleifen
Eine weitere Ursache für schlechte Vektorisierung sind zu große oder zu
komplizierte Schleifen. Obwohl der Compiler auch Schleifen mit IFs in
vielen Fällen vektorisieren kann, nimmt doch die Geschwindigkeit
gegenüber Schleifen ohne IF ab. Man sollte daher immer versuchen, IFs aus
Schleifen zu ziehen und sie, falls möglich, zu zerhacken. Die Auswirkungen
dieser Strategie sehen wir an folgendem Beispiel:
PROGRAMM BEISPIEL
REAL*4 A(100,100)
CALL MAKE_ID1(A,100)
CALL MAKE_ID2(A,100)
END
SUBROUTINE MAKE_ID1(A,N)
REAL*4 A(N,N)
INTEGER N
INTEGER I, J
DO I = 1, N
DO J = 1, N
IF (I .EQ. J) THEN
A(I, J) = 1.0
ELSE
A(I, J) = 0.0
ENDIF
ENDDO
ENDDO
END
SUBROUTINE MAKE_ID2(A,N)
REAL*4 A(N,N)
INTEGER N
INTEGER I, J
DO I = 1, N
DO J = 1, N
A(I, J) = 0.0
ENDDO
A(I, I) = 1.0
ENDDO
END
Obwohl in MAKE_ID2 die Diagonal-Elemente zweimal besetzt werden, zeigt eine
Laufzeit-Analyse mit dem CXpa, daß diese Routine fast 6x schneller läuft!
Zum Vergleich die Zeiten jeweils für -O1 und -O2:
Routine -O1 -O2
MAKE_ID1 3.354m 0.571m
MAKE_ID2 1.737m 0.106m
Normalerweise würde man sich wohl mit dem Vektorisierungsgewinn von
MAKE_ID1 zufrieden geben - und dabei eine ganze Menge verschenken!
Peter Junglas 18.10.1993