как использовать барьер omp в цикле while без равного количества итераций для потоков

Я пытаюсь реализовать проблему ранжирования списка (известную также путем сокращения) с помощью omp, чтобы иметь префиксы сумм массива W. Я не знаю, правильно ли я использую прагму flush. И у меня есть предупреждение при компиляции «барьера регион не может быть тесно вложен в область совместного использования, критических, упорядоченных, основных или явных задач"

#include <stdio.h> 
#include <stdlib.h>
#include <math.h>
#include <omp.h>

main(int argc, char *argv[])
{ 
  int Q[9]={1,2,3,4,5,6,7,8,0};
  int W[8]={1,2,3,4,5,6,7,8};
  int i,j=6,id;

  printf("Before:\n");
  for(j=0;j<8;j++)
  printf("%d",W[j]);
  printf("\n");
  #pragma omp parallel for shared(Q,W) private(id) num_threads(7)
  for (i=6; i>=0; i--)
  {
    id= omp_get_thread_num();
    while((Q[i] !=0)&& (Q[Q[i]] !=0))
    { 
      #pragma omp flush(W)

       W[i]=W[i]+W[Q[i]];

      #pragma omp flush(W)

       printf("Am %d \t W[%d]= %d",id,i,W[i]);

     #pragma omp barrier    
     #pragma omp flush(Q)
     Q[i]=Q[Q[i]];
     #pragma omp flush(Q)
     printf("Am %d \n Q[%d]= %d",id,i,Q[i]);
   };
 }
  printf("Result:\n");
  for(j=0; j<8; j++)
   printf("%d \t",W[j]);
   printf("\n");

}

ПОЖАЛУЙСТА ПОМОГИТЕ!


person maya    schedule 24.12.2009    source источник


Ответы (1)


Вы не можете использовать барьер внутри omp-параллели, вы можете использовать барьер только внутри omp-параллели.

Причина этого в том, что если ваш цикл от 1 до N, барьер внутри эффективно создаст N потоков, которые окажут негативное влияние на производительность, если N велико.

Я не искал алгоритм здесь, но есть два разумных варианта: провести рефакторинг для использования двух параллельных циклов for один за другим там, где находится барьер, или реорганизовать ваш алгоритм для использования параллельной области #pragma.

Я просмотрел алгоритм ранжирования списка, вам будет полезно найти реализацию суммы префиксов или сканирования, если вы должны использовать openmp.

-Рик

person Rick    schedule 25.12.2009
comment
Спасибо, Рик, я заметил, что нет необходимости использовать барьер в петле. Я поставил #pragma omp flush(Q) и #pragma omp flush(W) после изменения значений Q[i] и W[i], но у меня все еще есть проблема, когда другой поток выполняет сброс до того, как другой изменит свой Q [Я ценю. - person maya; 25.12.2009
comment
Maya, если вы работаете в Windows, взгляните на библиотеку параллельных шаблонов в VS2010, мы реализовали сканирование префиксов в качестве примера на code.msdn.com/concrtextras. Если вы не используете Windows, в строительных блоках потоков Intel реализовано сканирование. Вы также можете взглянуть на пример и заменить parallel_for на openmp для. - person Rick; 27.12.2009