Jaka jest różnica między tymi dwoma?
[ZA]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
Myślę, że nie ma żadnej różnicy, jeden jest skrótem dla drugiego. Chociaż Twoja dokładna implementacja może radzić sobie z nimi inaczej.
Połączone konstrukcje równoległego współdzielenia pracy są skrótem do określania konstrukcji równoległej zawierającej jedną konstrukcję współdzielenia pracy i żadnych innych instrukcji. Dozwolone klauzule to suma klauzul dozwolonych dla konstruktów równoległych i współdzielonych.
Zaczerpnięto z http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf
Specyfikacje dla OpenMP są tutaj:
Te są równoważne.
#pragma omp parallel
spawnuje grupę wątków, podczas gdy #pragma omp for
dzieli iteracje pętli między zwołanymi wątkami. Możesz zrobić obie rzeczy naraz dzięki #pragma omp parallel for
dyrektywie fused .
schedule(static, chunk)
klauzuli w dyrektywie for, pojawia się problem. Kod działa dobrze, ale kiedy wywołuję ten kod z programu MPI, uruchamia się w nieskończonej pętli. Licznik pętli wynosi zero we wszystkich iteracjach tej pętli. Mam licznik pętli zdefiniowany jako prywatny w#pragma omp parallel
dyrektywie. Nie mam pojęcia, dlaczego zawodzi tylko wtedy, gdy MPI wywołuje kod. Jestem pewien, że każdy proces MPI działa na innym procesorze klastra, jeśli ma to znaczenie. Nie mam pojęcia, czy harmonogram powoduje problem.#pragma omp parallel for
dyrektywy. Powinna być jakaś różnica.Oto przykład użycia separacji
parallel
ifor
tutaj . Krótko mówiąc, może być używany do dynamicznego przydzielania prywatnych tablic wątków OpenMP przed wykonaniemfor
cyklu w kilku wątkach. Niemożliwe jest wykonanie tej samej inicjalizacji wparallel for
przypadku.UPD: W przykładzie z pytaniem nie ma różnicy między jedną a dwiema pragmami. Ale w praktyce możesz sprawić, by zachowanie bardziej świadome wątku było oddzielone dyrektywy równoległe i dla dyrektyw. Na przykład jakiś kod:
źródło
Chociaż obie wersje konkretnego przykładu są równoważne, jak już wspomniano w innych odpowiedziach, nadal istnieje między nimi niewielka różnica. Pierwsza wersja zawiera niepotrzebną ukrytą barierę, napotkaną na końcu „omp for”. Drugą ukrytą barierę można znaleźć na końcu obszaru równoległego. Dodanie „nowait” do „omp for” spowodowałoby, że te dwa kody byłyby równoważne, przynajmniej z punktu widzenia OpenMP. Wspominam o tym, ponieważ kompilator OpenMP może wygenerować nieco inny kod dla obu przypadków.
źródło
Widzę zupełnie inne środowiska wykonawcze, gdy biorę pętlę for w g ++ 4.7.0 i używam
kod seryjny (no
openmp
) działa w 79 ms. kod „równoległy dla” działa w 29 ms. Jeśli pominąćfor
i użyć#pragma omp parallel
, pędy uruchomieniowe do 179ms, które jest wolniejsze niż kod seryjny. (maszyna ma współbieżność Hw 8)kod prowadzi do
libgomp
źródło
#pragma omp for
pętli nie ma w ogóle wielowątkowego udostępniania pętli. Ale i tak nie był to przypadek OP, spróbuj ponownie z dodatkowym#pragma omp for
wewnątrz#pragm omp parallel
i powinien działać podobnie (jeśli nie taki sam) jak#pragma omp parallel for
wersja.Odpowiedzi jest oczywiście mnóstwo, ale ta odpowiada na nie bardzo ładnie (ze źródłem)
i:
https://bisqwit.iki.fi/story/howto/openmp/
źródło