Я пытаюсь научиться параллельное программирование с OpenMP, и я заинтересован в распараллеливание следующий do while
цикл с несколькими while
петли внутри него:Как распараллелить do while и while loop в 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);
Я на самом деле не понял, как распараллелить while
и do while
петли, не удалось найти какой-либо ресурс, где он конкретно описывает, как распараллелить while
и do while
. Я нашел инструкции для петель for
, но я не мог сделать никаких предположений для while
и do while
циклов. Итак, не могли бы вы описать, как я могу распараллелить эти циклы, которые я здесь представил?
РЕДАКТИРОВАТЬ
Я превратил do while
петли в следующем код, где используются только for
цикла.
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;
}
}
Этот код прекрасно работает и дает правильный результат, но когда я попытался распараллеливание части выше указанного кода, путем изменения первых двух for
петли на следующее:
#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;
}
}
}
Скорость хуже, чем нераспарализованный код. Пожалуйста, помогите мне определить мою проблему.
Благодаря
Каково типичное значение для 'length'? – damienfrancois
Прежде чем использовать OpenMP, просто подумайте о том, как задача может выполняться параллельно. Подумайте о том, что у вас есть несколько парней, которым вы можете дать задания, ваши потоки. Теперь, чем вы занимаетесь? Что точно можно сделать параллельно в то время? С помощью for вы можете легко сказать: «для пробегов по индексу, для каждого индекса, вычисление может выполняться параллельно». Передавая каждому парню индекс или говоря им, чтобы вытащить указатель из ведра, обработайте его, а затем получите следующий. Но что-то вроде 'while (true) {if (condition) {break;} do_stuff; } '? Я вообще не вижу здесь концепции. – Aziuth
Что касается сортировки, как насчет слияния сортировки? Возьмите массив, разделите его на T-интервалы для потоков T, выполните их параллельно и затем последовательно объедините их. Слияние принимает O (N). Слияние сортировки интервалов принимает обычный O (NlogN), но является независимым и поэтому может выполняться параллельно. Для большого N в процессе слияния преобладает разделенная сортировка в пределах интервалов. То есть, если вы действительно хотите сделать это как упражнение. Если вы просто хотите, чтобы что-то сортировалось параллельно, вы получаете библиотеку, которая это делает. Вы не сможете конкурировать с хорошей библиотекой. – Aziuth