Это пример цикла с зависимостями, переносимыми циклом , и поэтому его нельзя легко распараллелить, как написано, потому что задачи (каждая итерация цикла) не являются независимыми. Нарушение зависимости может варьироваться от тривиальной модификации до абсолютно невозможной
(например, итерационный цикл).
Здесь случай немного посередине. Проблема с выполнением этого параллельно заключается в том, что вам нужно выяснить, какое будет ваше самое правое значение, прежде чем ваш сосед изменит значение. OMP для конструкции не раскрывает вам, какие значения итераций цикла будут «вашими», поэтому я не думаю, что вы можете использовать OpenMP для конструкции разделения, чтобы разорвать цикл. Тем не менее, вы можете сделать это самостоятельно; но это требует намного больше кода, и это не будет приятно сводиться к последовательному случаю больше.
Но все же пример того, как это сделать, показан ниже. Вы должны сами разорвать петлю, а затем получить самое правильное значение. Барьер OpenMP гарантирует, что никто не начнет изменять значения, пока все потоки не закэшируют свое новое самое правое значение.
#include <stdio.h>
#include <stdlib.h>
#include <omp.h>
int main(int argc, char **argv) {
int i;
char *array;
const int n=27;
array = malloc(n * sizeof(char) );
for (i=0; i<n-1; i++)
array[i] = 'A'+i;
array[n-1] = '\0';
printf("Array pre-shift = <%s>\n",array);
#pragma omp parallel default(none) shared(array) private(i)
{
int nthreads = omp_get_num_threads();
int tid = omp_get_thread_num();
int blocksize = (n-2)/nthreads;
int start = tid*blocksize;
int end = start + blocksize - 1;
if (tid == nthreads-1) end = n-2;
/* we are responsible for values start...end */
char rightval = array[end+1];
#pragma omp barrier
for (i=start; i<end; i++)
array[i] = array[i+1];
array[end] = rightval;
}
printf("Array post-shift = <%s>\n",array);
return 0;
}