Harmonogram OpenMP (statyczny) bez określonego rozmiaru porcji: rozmiar porcji i kolejność przypisania
Mam kilka pytań dotyczących#pragma omp for schedule(static)
gdzie rozmiar porcji nie jest określony.
Jednym ze sposobów na równoległość pętli w OpenMP jest ręczne wykonanie tego w następujący sposób:
#pragma omp parallel
{
const int nthreads = omp_get_num_threads();
const int ithread = omp_get_thread_num();
const int start = ithread*N/nthreads;
const int finish = (ithread+1)*N/nthreads;
for(int i = start; i<finish; i++) {
//
}
}
Czy istnieje dobry powód, aby nie robić ręcznie równoległej pętli takiej jak ta w OpenMP? Jeśli porównuję wartości z#pragma omp for schedule(static)
Widzę, że rozmiary porcji dla danego wątku nie zawsze się zgadzają, więc OpenMP (w GCC) implementuje rozmiary uchwytów inne niż zdefiniowane wstart
ifinish
. Dlaczego to?
Thestart
ifinish
zdefiniowane przeze mnie wartości mają kilka dogodnych właściwości.
Edytować: Oryginał Powiedziałem dokładnie jedną porcję, ale po zastanowieniu możliwe jest, że rozmiar porcji będzie równy zero, jeśli liczba wątków jest znacznie większa niżN
(ithread*N/nthreads = (ithread*1)*N/nthreads
). Nieruchomość, której naprawdę chcę, to co najwyżej jeden kawałek.
Czy wszystkie te właściwości są gwarantowane podczas używania#pragma omp for schedule(static)
?
Zgodnie ze specyfikacjami OpenMP:
Programy zależne od tego, który wątek wykonuje określoną iterację w innych okolicznościach, są niezgodne.
i
Różne regiony pętli o tym samym harmonogramie i liczbie iteracji, nawet jeśli występują w tym samym regionie równoległym, mogą rozdzielać racje między wątkami inaczej. Jedynym wyjątkiem jeststatyczny harmonogram
Dlaschedule(static)
specyfikacja mówi:
kawałki są przypisywane do wątków w zespole w okrągły sposób w kolejności numeru wątku.
Dodatkowo specyfikacja mówi o `harmonogramie (statyczny):
Jeśli nie określono wielkości chunk_size, przestrzeń iteracji jest podzielona na porcje, które są w przybliżeniu równe pod względem wielkości, a co najwyżej jedna porcja jest rozprowadzana do każdego wątku.
Wreszcie mówi specyfikacjaschedule(static)
:
Zgodna implementacja harmonogramu statycznego musi zapewnić, że to samo przypisanie logicznych numerów iteracji do wątków będzie używane w dwóch regionach pętli, jeśli spełnione zostaną następujące warunki: 1) oba regiony pętli mają taką samą liczbę iteracji pętli, 2) obie pętle regiony mają tę samą wartość podanej wielkości fragmentu lub oba regiony pętli nie mają określonej wielkości fragmentu, 3) oba regiony pętli wiążą się z tym samym regionem równoległym.
Więc jeśli dobrze to przeczytamschedule(static)
będzie miał te same wygodne właściwości, które wymieniłem jakostart
ifinish
nawet jeśli mój kod opiera się na wątku, wykonuje określoną iterację.Czy interpretuję to poprawnie? To wydaje się być szczególnym przypadkiemschedule(static)
gdy rozmiar porcji nie jest określony.
Łatwiej jest po prostu zdefiniowaćstart
ifinish
tak jak wtedy, spróbowałem przerwać specyfikację tego przypadku.