2016-03-23 9 views
3

ich habe folgende Fortran-Code geschrieben atomic zu testen und criticalWarum OpenMP atomare und kritische geben nicht das richtige Ergebnis?

program test 
    implicit none 
    integer::i 
    integer::a(10),b(10),atmp(10),btmp(10) 
    a=[1,2,3,4,5,6,7,8,9,10] 
    b=[12,32,54,77,32,19,34,1,75,45] 
    atmp=a 
    btmp=b 
    write(*,'(1X,10I4)') a+b 
    print*,'------------------' 
    !$omp parallel 
    !$omp do 
    do i=1,10 
     B(I) = B(I)+A(I) 
    end do 
    !$omp end do 
    !$omp single 
    write(*,'(1X,10I4)') b 
    !$omp end single 

    a=atmp 
    b=btmp 
    !$omp do 
    do i=1,10 
     !$omp critical 
     B(I) = B(I)+A(I) 
     !$omp end critical 
    end do 
    !$omp end do 
    !$omp single 
    write(*,'(1X,10I4)') b 
    !$omp end single 

    a=atmp 
    b=btmp 
    !$omp do 
    do i=1,10 
     !$omp atomic 
     B(I) = B(I)+A(I) 
     !$omp end atomic 
    end do 
    !$omp end do 
    !$omp single 
    write(*,'(1X,10I4)') b 
    !$omp end single 

    !$omp end parallel 
end program 

Der Ausgang ist

enter image description here

Es bedeutet, dass aufgrund der atomic und critical falsch ist. Das ist merkwürdig, ich dachte, sie könnten den Rennzustand vermeiden. Aber die erste Schleife ohne Synchronisation gibt die richtige Antwort, gibt es hier kein Rennen? Was ist falsch an meinem Code?

+0

Was ist das erwartete richtige Ergebnis? Ist es über der Linie? Es wäre besser, diese als Text aufzunehmen. Das Bild könnte nach einiger Zeit vom Hosting gelöscht werden. –

+0

Ich denke, die Race Condition ist eigentlich der 'a = atmp; b = btmp' in der parallelen Region. Aber ich habe den Code nicht zu lange studiert. –

+0

@HighPerformanceMark Ich habe diese Art der Nutzung auf Seite 92 http://openmp.org/mp-documents/openmp-examples-4.0.2.pdf gesehen. Der Doc zeigt dies als eine typische Verwendung von Atom, ist es nicht richtig? – user15964

Antwort

6

Das Problem in Ihrem Code ist die Race-Bedingung

!$omp parallel 

... 
    a=atmp 
    b=btmp 
... 
    !$omp end parallel 

alle Threads, dass der Betrieb tun, und sie kollidieren. Sie möchten omp single um diese Zeilen.

Sie benötigen keine atomic oder critical in

!$omp do 
do i=1,10 
    B(I) = B(I)+A(I) 
end do 
!$omp end do 

weil jeder Thread auf einem anderen Array-Element arbeitet.

In Ihrem Beispiel aus der OpenMP-Spezifikation ist das Problem, dass in

!$OMP PARALLEL DO SHARED(X, Y, INDEX, N) 
DO I=1,N 
    !$OMP  ATOMIC UPDATE 
    X(INDEX(I)) = X(INDEX(I)) + WORK1(I) 

das Array oder eine Funktion INDEX(I) kann den gleichen Wert für zwei verschiedene Threads mit einer anderen I zurückkehren und Sie müssen diese potenzielle Racebedingung schützen.

+0

Vielen Dank für Ihre nette Antwort! – user15964

Verwandte Themen