2016-08-04 25 views
0

Ich möchte diesen Code unten (nur für ein Beispiel) vektorisieren, einfach davon ausgehen, irgendwie sollte ich ein Array in einem Array schreiben.Könnte der Compiler das Looping mit einem Array vektorisieren, das aus einem Array innerhalb besteht?

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 

dachte ich zum ersten Mal, dass Compiler verstehen kann, was ich will, was irgendwie wie diese vektorisiert werden:

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 

aber ich war falsch. Ich benutzte: gfortran -Ofast -o -fopt-info-optimized Tes.F95 und ich bekam die Information, dass nur die erste Schleife erfolgreich vektorisiert werden konnte.

Haben Sie eine Idee, wie ich es vektorisieren könnte? Oder kann es überhaupt nicht vektorisiert werden?

+0

Wenn Sie indirekte Indexierung verwenden (dh wie in Ihren Ausdrücken wie "A (E (I))"), haben Sie kein vernünftiges Recht, Elemente wie "A (E (I- 1)) und 'A (E (I + 1))' in der Nähe zu sein. Die Vektorisierung hängt davon ab, dass der Prozessor in der Lage ist, eine Anzahl benachbarter Array-Elemente auf seine f-p-Einheiten in einem Chunk zu streamen. Ich habe nicht viel darüber nachgedacht, aber es fällt mir auf, dass die indirekte Adressierung wahrscheinlich nicht mit der Vektorisierung vereinbar ist. In HPC ist es nicht unbekannt, Array-Elemente genau neu zu ordnen, um die Vorteile der räumlichen Lokalisierung von Daten zu nutzen. –

+0

@HighPerformanceMark: Mit anderen Worten, die Vektorisierung durch den Compiler ist nur möglich mit DIRECT INDEXING, wie auf den DO-Anweisungen geschrieben? –

+0

Das ist mein Denken, aber ich bin bereit, etwas anderes zu sagen. Warum nicht etwas Zeit mit Bleistift und Papier verbringen und etwas davon für sich herausfinden. –

Antwort

1

Wenn E gleiche Werte für verschiedene I sind, dann würden Sie die gleichen Elemente von A mehrmals manipulieren, in welchem ​​Fall die Reihenfolge von Bedeutung sein könnte. (Obwohl nicht in Ihrem Fall.) Auch, wenn Sie mehr Index-Arrays, wie E1, E2 und E3 und

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

die Reihenfolge Materie könnte. Ich denke, diese Art der Indizierung ist im Allgemeinen nicht in parallelen Schleifen erlaubt.

+0

Henne hej, ich sehe wir denken gleich Herr Ostrom! – Holmz

+0

Compiler, die dies automatisch vektorisieren, behalten die Reihenfolge der Speicherung im Falle von Duplikaten bei (es sei denn, Sie weisen direkt darauf hin, dass es Ihnen egal ist). Falls es nicht offensichtlich ist, können sich die Arrays in dem geposteten Beispiel nicht überlappen (was trivial genug ist, um möglicherweise zu nichts optimiert zu werden). – tim18

+0

@ tim18 ok, aber es scheint, dass er tatsächlich einen Fehler (oder "Information") beim Kompilieren bekommen, aber Sie meinen, dies ist, weil seine Hardware dies nicht unterstützt? Ich denke nicht, dass OpenMP es erlauben würde, aber ich habe diese spezielle Anordnung nicht ausprobiert. –

0

Mit ifort kann man! DIR $ IVDEP verwenden, die "Vektorabhängigkeit ignorieren" ist. Es funktioniert nur, wenn E (I) wie im Beispiel linear ist ...

Angenommen, man möchte alle Indizes machen, dann einfach (E (i)) durch (I) ersetzen und das offensichtliche E (I) später bestellen ...