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)
{
...
}
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)
{
...
}
Odpowiedzi:
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 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 .
#pragma omp parallel fordyrektywy. Powinna być jakaś różnica.
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
}
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.
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
#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.
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.
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.