Jaka jest różnica między atomową a krytyczną w OpenMP?
mogę to zrobić
#pragma omp atomic
g_qCount++;
ale to nie to samo co
#pragma omp critical
g_qCount++;
?
źródło
Jaka jest różnica między atomową a krytyczną w OpenMP?
mogę to zrobić
#pragma omp atomic
g_qCount++;
ale to nie to samo co
#pragma omp critical
g_qCount++;
?
Wpływ na g_qCount jest taki sam, ale to, co zostało zrobione, jest inne.
Sekcja krytyczna OpenMP jest całkowicie ogólna - może otaczać dowolny blok kodu. Płacisz jednak za tę ogólność, ponosząc znaczny narzut za każdym razem, gdy wątek wchodzi i wychodzi z sekcji krytycznej (oprócz nieodłącznego kosztu serializacji).
(Ponadto w OpenMP wszystkie nienazwane sekcje krytyczne są uważane za identyczne (jeśli wolisz, jest tylko jedna blokada dla wszystkich nienazwanych sekcji krytycznych), więc jeśli jeden wątek znajduje się w jednej [nienazwanej] sekcji krytycznej, jak powyżej, żaden wątek nie może wejść do żadnego [nienazwana] sekcja krytyczna. Jak możesz się domyślić, możesz obejść ten problem, używając nazwanych sekcji krytycznych).
Operacja atomowa ma znacznie niższe koszty ogólne. Tam, gdzie to możliwe, wykorzystuje sprzęt zapewniający (powiedzmy) atomową operację inkrementacji; w takim przypadku nie ma potrzeby blokowania / odblokowywania przy wchodzeniu / wychodzeniu z wiersza kodu, po prostu wykonuje atomowy przyrost, o którym sprzęt mówi, że nie można w niego ingerować.
Zaletą jest to, że narzut jest znacznie niższy, a jeden wątek będący w operacji atomowej nie blokuje żadnych (różnych) operacji atomowych, które mają się wydarzyć. Wadą jest ograniczony zestaw operacji obsługiwanych przez atomic.
Oczywiście w każdym przypadku ponosisz koszty serializacji.
++
i*=
), a jeśli nie są one wspierane sprzętowo, mogą one zostać zastąpione przezcritical
sekcje.W OpenMP wszystkie nienazwane sekcje krytyczne wzajemnie się wykluczają.
Najważniejszą różnicą między krytycznym a atomowym jest to, że atomic może chronić tylko jedno przypisanie i możesz go używać z określonymi operatorami.
źródło
Krytyczny fragment:
Można rozszerzyć o serializację grup bloków z odpowiednim użyciem tagu „nazwa”.
Wolniej!
Operacja atomowa:
Jest dużo szybszy!
Zapewnia tylko serializację określonej operacji.
źródło
Najszybszy sposób nie jest ani krytyczny, ani atomowy. W przybliżeniu dodawanie z sekcją krytyczną jest 200 razy droższe niż zwykłe dodawanie, dodawanie atomów jest 25 razy droższe niż proste dodawanie.
Najszybszą opcją (nie zawsze stosowaną) jest przypisanie każdemu wątkowi własnego licznika i ograniczenie operacji, gdy potrzebna jest całkowita suma.
źródło
Ograniczenia
atomic
są ważne. Powinny być szczegółowo opisane w specyfikacji OpenMP . MSDN oferuje szybką ściągawkę, ponieważ nie zdziwiłbym się, gdyby to się nie zmieniło. (Visual Studio 2012 ma implementację OpenMP od marca 2002). Aby zacytować MSDN:Zalecam używać,
atomic
kiedy możesz, i nazwać sekcje krytyczne w inny sposób. Nazwanie ich jest ważne; w ten sposób unikniesz debugowania problemów.źródło
Już świetne wyjaśnienia tutaj. Możemy jednak zanurkować nieco głębiej. Aby zrozumieć podstawową różnicę między koncepcjami sekcji atomowej i krytycznej w OpenMP, musimy najpierw zrozumieć koncepcję blokady . Przyjrzyjmy się, dlaczego musimy używać blokad .
Aby zsynchronizować wątki w programie wielowątkowym, użyjemy blokady . Gdy dostęp ma być ograniczony tylko przez jeden wątek na raz, w grę wchodzą blokady . Blokada realizacja koncepcji może się różnić od procesora do procesora. Zobaczmy, jak prosta blokada może działać z algorytmicznego punktu widzenia.
Podany algorytm można zaimplementować w języku sprzętowym w następujący sposób. Przyjmiemy jeden procesor i przeanalizujemy zachowanie blokad w tym. W tym celu przyjmijmy jeden z następujących procesorów: MIPS , Alpha , ARM lub Power .
Ten program wydaje się być w porządku, ale tak nie jest. Powyższy kod ma poprzedni problem; synchronizacja . Znajdźmy problem. Załóżmy, że początkowa wartość blokady wynosi zero. Jeśli dwa wątki uruchamiają ten kod, jeden może dotrzeć do SW R1, zablokować, zanim drugi odczyta zmienną lock . Dlatego oboje uważają, że zamek jest bezpłatny. Aby rozwiązać ten problem, podano inną instrukcję zamiast prostej LW i SW . Nazywa się to instrukcją odczytu, modyfikacji i zapisu . Jest to złożona instrukcja (składająca się z podinstrukcji), która zapewnia jednoczesne uzyskanie blokady procedurę wykonuje tylko jedenwątku na raz. Różnica między odczytem, modyfikacją i zapisem ww porównaniu z prostymi instrukcjami odczytu i zapisu jest to inny sposób ładowania i przechowywania . Używa LL (Load Linked) do ładowania zmiennej blokady i SC (Store Conditional) do zapisywania w zmiennej lock. Dodatkowy rejestr linków służy do zapewnienia, że procedura pozyskiwania blokady jest wykonywana przez pojedynczy wątek. Algorytm podano poniżej.
Gdy rejestr łącza zostanie zresetowany, jeśli inny wątek założył, że blokada jest wolna, nie będzie mógł ponownie zapisać zwiększonej wartości do blokady. Zatem współbieżność dostępu do zamka zmiennej .
Podstawowa różnica między krytycznym a atomowym wynika z pomysłu, że:
Użycie nowej zmiennej dla blokad doprowadzi do sekcji krytycznej , podczas gdy użycie rzeczywistej zmiennej jako blokady doprowadzi do koncepcji atomowej . Sekcja krytyczna jest przydatna, gdy wykonujemy wiele obliczeń (więcej niż jeden wiersz) na rzeczywistej zmiennej. Dzieje się tak, ponieważ jeśli wynik tych obliczeń nie zostanie zapisany na rzeczywistej zmiennej, całą procedurę należy powtórzyć, aby obliczyć wyniki. Może to prowadzić do słabej wydajności w porównaniu z oczekiwaniem na zwolnienie blokady przed wejściem do obszaru wymagającego dużej mocy obliczeniowej. Dlatego zaleca się użycie dyrektywy atomic, gdy chcesz wykonać pojedyncze obliczenia (x ++, x--, ++ x, --x itp.) I użyć dyrektywy krytycznej, gdy sekcja intensywna zajmuje się bardziej złożonym obliczeniowo regionem.
źródło
atomic jest stosunkowo wydajne, gdy trzeba włączyć wzajemne wykluczanie tylko dla jednej instrukcji, podobnie nie jest prawdą w przypadku omp krytycznego.
źródło
atomic to pojedyncza instrukcja Sekcja krytyczna, tzn. blokujesz wykonanie jednej instrukcji
sekcja krytyczna to blokada na bloku kodu
Dobry kompilator przetłumaczy twój drugi kod w taki sam sposób jak pierwszy
źródło