Próbuję uczyć się programowania równoległego z OpenMP i jestem zainteresowany parallelizing następujące do while
pętlę z kilku while
pętli wewnątrz niego:Jak wykonać równoległość do pętli while i while w openmp?
do {
while(left < (length - 1) && data[left] <= pivot) left++;
while(right > 0 && data[right] >= pivot) right--;
/* swap elements */
if(left < right){
temp = data[left];
data[left] = data[right];
data[right] = temp;
}
} while(left < right);
Nie rzeczywiście zorientowali się, jak parallelize while
i do while
w pętlach, nie można znaleźć żadnego zasobu, w którym opisuje on w sposób szczegółowy równoległościanie pętli while
i do while
. Znalazłem instrukcje dla pętli for
, ale nie mogłem założyć, że pętle z tego powodu są while
i do while
. Czy mógłbyś opisać, w jaki sposób mogę zrównoleglić te pętle, które tutaj podałem?
EDIT
I przekształca pętli do następnego kodu, w którym stosuje się tylko for
pętli do while
.
for(i = 1; i<length-1; i++)
{
if(data[left] > pivot)
{
i = length;
}
else
{
left = i;
}
}
for(j=length-1; j > 0; j--)
{
if(data[right] < pivot)
{
j = 0;
}
else
{
right = j;
}
}
/* swap elements */
if(left < right)
{
temp = data[left];
data[left] = data[right];
data[right] = temp;
}
int leftCopy = left;
int rightCopy = right;
for(int leftCopy = left; leftCopy<right;leftCopy++)
{
for(int new_i = left; new_i<length-1; new_i++)
{
if(data[left] > pivot)
{
new_i = length;
}
else
{
left = new_i;
}
}
for(int new_j=right; new_j > 0; new_j--)
{
if(data[right] < pivot)
{
new_j = 0;
}
else
{
right = new_j;
}
}
leftCopy = left;
/* swap elements */
if(left < right)
{
temp = data[left];
data[left] = data[right];
data[right] = temp;
}
}
Ten kod działa poprawnie i daje prawidłowy wynik, ale kiedy próbowałem parallelize części wyżej podanej kodu poprzez zmianę dwóch pierwszych for
pętle na następujące kwestie:
#pragma omp parallel default(none) firstprivate(left) private(i,tid) shared(length, pivot, data)
{
#pragma omp for
for(i = 1; i<length-1; i++)
{
if(data[left] > pivot)
{
i = length;
}
else
{
left = i;
}
}
}
#pragma omp parallel default(none) firstprivate(right) private(j) shared(length, pivot, data)
{
#pragma omp for
for(j=length-1; j > 0; j--)
{
if(data[right] < pivot)
{
j = 0;
}
else
{
right = j;
}
}
}
Prędkość jest gorszy niż nierównoległy kod. Pomóż mi zidentyfikować mój problem.
Dzięki
Jaka jest typowa wartość dla "długości"? – damienfrancois
Zanim zaczniesz korzystać z OpenMP, zastanów się, w jaki sposób zadanie można wykonać równolegle. Pomyśl o tym, że masz kilku facetów, którym możesz dawać zadania, swoje wątki. Co teraz robisz? Co dokładnie można zrobić równolegle od dłuższego czasu? Za pomocą for można łatwo powiedzieć "dla przebiegów nad indeksem, dla każdego indeksu obliczenia można wykonać równolegle". Wręczając każdemu facetowi indeks lub mówiąc mu, żeby wyłuskał indeks z wiadra, obsłużyć go, a następnie zdobyć następny. Ale w czymś takim jak 'while (true) {if (condition) {break;} do_stuff; } '? Generalnie nie widzę tutaj żadnej koncepcji. – Aziuth
Co do sortowania, a co powiesz na sortowanie scalone? Weź tablicę, podziel ją na interwały T dla wątków T, wykonaj je równolegle, a następnie połącz je sekwencyjnie. Scalanie trwa O (N), scalanie sortowania interwałów odbywa się zwykle O (NlogN), ale jest niezależne i dlatego może być wykonane równolegle. W przypadku dużego N proces łączenia jest zdominowany przez oddzielne sortowanie w interwałach. To znaczy, jeśli naprawdę chcesz to zrobić jako ćwiczenie. Jeśli chcesz, aby coś zostało posortowane równolegle, otrzymasz bibliotekę, która to robi. Nie będziesz w stanie konkurować z dobrą biblioteką. – Aziuth