Переупорядоченный вывод несмотря на критическую секцию - PullRequest
0 голосов
/ 02 ноября 2018

Я пытаюсь адаптировать эту программу с использованием треугольника Паскаля для параллельной программы с использованием OpenMp. Я использовал директиву for, чтобы распараллелить функцию printPas для цикла, и поместил условные операторы в критическую секцию, чтобы только один поток мог печатать за раз, но похоже, что я все еще получаю гонку данных, потому что мой вывод действительно противоречив.

#include <stdio.h>

#ifndef N
#define N 2
#endif
unsigned int t1[2*N+1], t2[2*N+1];
unsigned int *e=t1, *r=t2;
int l = 0;

//the problem is here in this function
void printPas() {
  #pragma omp parallel for private(l)
  for (l=0; l<2*N+1; l++) {
    #pragma omp critical
    if (e[l]==0)
      printf("      ");
    else
      printf("%6u", e[l]);
  }
  printf("\n");

}

void update() {
  r[0] = e[1];
#pragma omp parallel for
  for (int u=1; u<2*N; u++)
    r[u] = e[u-1]+e[u+1];
  r[2*N] = e[2*N-1];
  unsigned int *tmp = e; e=r; r=tmp; 
}

int main() {
  e[N] = 1;
  for (int i=0; i<N; i++) {
    printPas();
    update();
  }
  printPas();
}

1 Ответ

0 голосов
/ 02 ноября 2018

Ваш критический раздел заставляет отпечатки работать последовательно. Поэтому при использовании «критического» кода требуется больше времени, чем если бы вы не пытались распараллелить его.

Используя различные потоки для печати, вы не представляете, какой из них первым получит доступ к критическому разделу. Поэтому цикл for не будет выполняться в том порядке, в котором вы надеетесь.

Я предлагаю либо удалить параллельную директиву («#pragma omp parallel for private (l)»), либо удалить «критическую» и принять, что отпечатки будут выходить в другом порядке каждый раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...