5

Jeśli używam wspólnej zmiennej, powiedzmy podwójnej, aby obliczyć jakąś sumę w trakcie wykonywania programu. Czy w każdym razie byłaby podatna na niestabilne operacje? To znaczy, czy byłoby możliwe, że więcej niż jeden rdzeń uzyskałby dostęp do tej zmiennej w sposób asynchroniczny i powodowałby niestabilność wyników?C++: Ochrona pamięci współdzielonej OpenMP

Na przykład: jest to zmienna globalna:

double totalTime = 0; 

aw każdym rdzeniu polecenie nazywa się:

totalTime += elapsedTime; 

Ta ostatnia operacja/instrukcja wykonywana jest poprzez wartość totalTime , umieść go w rejestrze procesora, a następnie dodaj. Mogę sobie wyobrazić, że więcej niż jeden rdzeń przyjmie taką samą wartość w tej samej chwili, a następnie doda nowy czas, który upłynął, a następnie wartość zapisana w totalTime zostanie nadpisana z niewłaściwą wartością, z powodu opóźnienia. Czy to jest możliwe? i jak mogę to rozwiązać?

Dziękuję.

Odpowiedz

4

Oczywiście ta operacja nie jest bezpieczna dla wątków, ponieważ, jak wspomniałeś, zawiera kilka instrukcji asemblera. W rzeczywistości openMP ma nawet specjalną dyrektywę dla tego rodzaju operacji.

Będziesz potrzebował atomic pragmy zrobić to dobrze, „atomowej”:

#pragma omp atomic 
totalTime += elapsedTime; 

Zauważ, że atomic działa tylko wtedy, gdy masz jedną aktualizację do lokalizacji pamięci, niczym więcej, przyrost, etc .

Jeśli masz szereg wskazówek, które muszą atomowej razem trzeba użyć dyrektywy critical:

#pragma omp critical 
{ 
    // atomic sequence of instructions 
} 

Edit: Oto dobra propozycja z „snemarch”: Jeśli wielokrotnie aktualizowania zmienną globalną totalTime w równoległej pętli można rozważyć użycie klauzuli reduction zautomatyzować ten proces, a także sprawiają, że o wiele bardziej wydajny:

double totalTime = 0; 

#pragma omp parallel for reduction(+:totalTime) 
for(...) 
{ 
    ... 
    totalTime += elapsedTime; 
} 

Pod koniec totalTime będzie poprawnie zawierać sumę lokalnych wartości elapsedTime bez potrzeby jawnej synchronizacji.

+0

Dzięki, kolego :) –

+0

Zastanawiam się, w jaki sposób OpenMP obsługuje rozszerzenia atomowe dla typów danych zmiennoprzecinkowych na x86 - nie ma natywnej instrukcji dla tego. Sekcje krytyczne? – snemarch

+0

@snemarch: Nie mogłem znaleźć niczego ostatecznego, więc domyślam się, że używa zamków. – Tudor

Powiązane problemy