2016-08-07 30 views
2

Ich arbeite mit diesen Codes (wie ich unten 2 Codes poste: das Original und mit omp Simd Funktion Vektorisierung).Gibt es eine Möglichkeit, die "if-else" -Bedingung mithilfe der omp-simd-Funktions- vektorisierung zu vektorisieren?

Dies ist der ursprüngliche Code, dass ich vektorisieren wollen:

PROGRAM TEST 
    IMPLICIT NONE 
    REAL(KIND=8), DIMENSION(2000):: A,B,C 
    REAL(KIND=8)::TIME1,TIME2 
    INTEGER::I,K 

    !Initial condition  
    !$OMP SIMD   !This part of course could be vectorized 
     DO I=1, 2000  !even without !$OMP SIMD statement 
     A(I)=2.0+I/100 
     B(I)=1.0+I/200 
     C(I)=0.2+I/500   
     END DO  
    !$OMP END SIMD 

    CALL CPU_TIME(TIME1) 

    DO K=1, 1000000 
     !$OMP SIMD    !This part which I want to vectorize 
     DO I=1, 2000   !but of course it was not, since 
      IF(A(I)>0.0) THEN !if-else statement exists 
       C(I)=A(I)+B(I)       
      ELSE 
       C(I)=2.0*I   
      END IF   
     END DO 
     !$OMP END SIMD   
    END DO  

    CALL CPU_TIME(TIME2) 

    PRINT *, 'C(2000)   = ', C(2000) 
    PRINT *, 'Elapsed real time = ', TIME2-TIME1, 'second(s)' 
END PROGRAM TEST 

Ich weiß, wann die „if-else“ Anweisung existiert, wird der Compiler nicht die automatische Vektorisierung tun konnte, und in meinem Fall es hat auch nicht funktioniert, sogar ich habe! $ OMP DO SIMD, was klar ist. Und meines Wissens kann nur die intrinsische Funktion vom Compiler automatisch vektorisiert werden.

Vor ein paar Tagen habe ich gerade eine Präsentation gelesen, die die Möglichkeit bietet, eine Funktion mit "OMP SIMD FUNCTION VECTORIZATION" zu vektorisieren. So versuche ich, den ursprünglichen Code wie folgt zu ändern:

PROGRAM TEST 
    IMPLICIT NONE 
    REAL(KIND=8), DIMENSION(2000):: A,B,C 
    REAL(KIND=8)::TIME1,TIME2 
    REAL(KIND=8), EXTERNAL::VEC 
    INTEGER::I,K 

    !Initial condition  
    !$OMP SIMD  
     DO I=1, 2000 
     A(I)=2.0+I/100 
     B(I)=1.0+I/200 
     C(I)=0.2+I/500   
     END DO  
    !$OMP END SIMD 

    CALL CPU_TIME(TIME1) 

    DO K=1, 1000000 
     !$OMP SIMD 
     DO I=1, 2000 
      C(I)=VEC(A(I),B(I),I)   
     END DO 
     !$OMP END SIMD   
    END DO  

    CALL CPU_TIME(TIME2) 

    PRINT *, 'C(2000)   = ', C(2000) 
    PRINT *, 'Elapsed real time = ', TIME2-TIME1, 'second(s)' 
END PROGRAM TEST 

FUNCTION VEC(IN1,IN2,IN3) RESULT(OUT1) 
IMPLICIT NONE 
REAL(KIND=8)::IN1,IN2,OUT1 
INTEGER::IN3 

      !IN1 = A(I) 
      !IN2 = B(I) 
      !IN3 = I 

    !$OMP DECLARE SIMD(VEC)  
      IF(IN1>0.0) THEN 
       OUT1=IN1+IN2        
      ELSE 
       OUT1=2.0*IN3   
      END IF   
END FUNCTION VEC 

aber die Vektorisierung funktionierte noch nicht. Hast du eine Idee, wie könnte ich damit vektorisieren! $ OMP SIMD? Oder es könnte auch nicht vektorisiert werden (es ist nur ein selbe Fall mit dem Fehler der automatischen Vektorisierung durch den Compiler, wenn nicht-intrinsische Funktion existiert)? Irgendwelche Hilfen werden geschätzt.

Antwort

0

Omp do simd innerhalb einer parallelen Region würde sowohl Threads als auch Simd-Vektorisierung anfordern. Ich nehme an, die Art, wie Sie es einem Compiler nennen, wäre berechtigt, es zu ignorieren oder eine Warnung zu geben. Omp simd benötigt keine parallele Region, falls Sie das beabsichtigt haben. Die Vektorisierung einer Bedingung ist wahrscheinlicher mit der Zusammenführungssyntax zu arbeiten.

+0

Danke. Aber ich habe nicht verstanden, was du meinst. Was ist deine Antwort auf meine Frage? Ist "Vektorisierung einer Bedingung ist wahrscheinlich mit Merge-Syntax zu arbeiten." Deine Antwort? Wenn ja, welche Art von "Merge-Syntax" meinst du? Vielen Dank. PS: Ja, ich weiß, dass ich in diesem Fall nur $ OMP SIMD anstelle von $ OMP DO SIMD schreiben muss. Ich habe es überarbeitet. –

+0

Die erste Version, die Sie auf der Intel-Website veröffentlicht haben, vektorisiert problemlos. Daher weiß ich nicht, warum Sie glauben, dass Sie Ihre Fehler nicht korrigiert haben. – tim18

+0

C (I) = verschmelzen (A (I) + B (I), 2.0 * I, A (I)> 0.0) sollte sogar mit gfortran -O3 -ffst-mathe – tim18