omp parallel vs. omp parallel dla

105

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)
{
   ...
}
Hyunjik Bae
źródło

Odpowiedzi:

65

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:

https://openmp.org/specifications/

Ade Miller
źródło
66

Te są równoważne.

#pragma omp parallelspawnuje grupę wątków, podczas gdy #pragma omp fordzieli iteracje pętli między zwołanymi wątkami. Możesz zrobić obie rzeczy naraz dzięki #pragma omp parallel fordyrektywie fused .

Krzysztof Kosiński
źródło
W moim kodzie używam właśnie tej struktury. Jednak kiedy używam 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 paralleldyrektywie. 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.
Rohit Banga
To samo działa dobrze, gdy używam #pragma omp parallel fordyrektywy. Powinna być jakaś różnica.
Rohit Banga
1
Aktualizacja: Jak się okazuje, obserwuję ten problem tylko wtedy, gdy używam klauzuli harmonogramu, więc myślę, że nie zależy to od tego, czy używam połączonego równoległego dla, czy dwóch różnych dyrektyw.
Rohit Banga
28

Oto przykład użycia separacji paralleli for tutaj . Krótko mówiąc, może być używany do dynamicznego przydzielania prywatnych tablic wątków OpenMP przed wykonaniem forcyklu w kilku wątkach. Niemożliwe jest wykonanie tej samej inicjalizacji w parallel forprzypadku.

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:

#pragma omp parallel
{ 
    double *data = (double*)malloc(...); // this data is thread private

    #pragma omp for
    for(1...100) // first parallelized cycle
    {
    }

    #pragma omp single 
    {} // make some single thread processing

    #pragma omp for // second parallelized cycle
    for(1...100)
    {
    }

    #pragma omp single 
    {} // make some single thread processing again

    free(data); // free thread private data
}
NtsDK
źródło
9

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.

phadjido
źródło
7

Widzę zupełnie inne środowiska wykonawcze, gdy biorę pętlę for w g ++ 4.7.0 i używam

std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;

for (int i = 0; i < 5000000; i++)
{
   double r1 = ((double)rand() / double(RAND_MAX)) * 5;
   double r2 = ((double)rand() / double(RAND_MAX)) * 5;
   x.push_back(r1);
   y.push_back(r2);
}

int sz = x.size();

#pragma omp parallel for

for (int i = 0; i< sz; i++)
   prod[i] = x[i] * y[i];

kod seryjny (no openmp) działa w 79 ms. kod „równoległy dla” działa w 29 ms. Jeśli pominąć fori 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

parcompute
źródło
2
Myślę, że dzieje się tak dlatego, że omp parallel wykonuje pętlę w oddzielnym wątku bez dzielenia go na wątki, więc główny wątek czeka na zakończenie drugiego wątku. a czas spędza na synchronizacji.
Antigluk
7
Dzieje się tak, ponieważ bez #pragma omp forpę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 forwewnątrz #pragm omp paralleli powinien działać podobnie (jeśli nie taki sam) jak #pragma omp parallel forwersja.
Christian Rau
2
Uważam tę odpowiedź za najlepszą, ponieważ pokazuje, że nie są one „równoważne”
Failed Scientist
6

Odpowiedzi jest oczywiście mnóstwo, ale ta odpowiada na nie bardzo ładnie (ze źródłem)

#pragma omp fordeleguje tylko części pętli dla różnych wątków w bieżącym zespole. Zespół to grupa wątków wykonujących program. Na początku programu zespół składa się tylko z jednego członka: wątku głównego, który uruchamia program.

Aby utworzyć nowy zespół wątków, musisz określić słowo kluczowe parallel. Można to określić w otaczającym kontekście:

#pragma omp parallel
{
   #pragma omp for
   for(int n = 0; n < 10; ++n)
   printf(" %d", n);
}

i:

Co to jest: równolegle, za i zespół

Różnica między równolegle, równolegle dla i dla jest następująca:

Zespół to grupa wątków, które są aktualnie wykonywane. Na początku programu zespół składa się z jednego wątku. Konstrukcja równoległa dzieli bieżący wątek na nowy zespół wątków na czas trwania następnego bloku / instrukcji, po czym zespół łączy się z powrotem w jeden. for dzieli pracę pętli for pomiędzy wątki obecnego zespołu.

Nie tworzy wątków, a jedynie dzieli pracę pomiędzy wątki aktualnie wykonującego zespołu. parallel for to skrót dla dwóch poleceń naraz: parallel i for. Parallel tworzy nowy zespół i dzieli ten zespół do obsługi różnych części pętli. Jeśli twój program nigdy nie zawiera konstrukcji równoległej, nigdy nie ma więcej niż jednego wątku; główny wątek, który uruchamia program i uruchamia go, tak jak w programach nie obsługujących wątków.

https://bisqwit.iki.fi/story/howto/openmp/

fogx
źródło