2015-09-19 4 views
0

Я пытаюсь выполнить код OpenMP и был успешным в этом. Однако у меня есть сомнения относительно заявления #pragma omp parallel.Почему этот код openmp дает ошибку сегментации?

Рассмотрим эти два фрагмента кода:

#pragma omp parallel firstprivate(my_amax) 
{ 
    for (i=0; i<MATRIX_DIM; i++) { 
     #pragma omp for 
     for (j=0; j<MATRIX_DIM; j++) { 
      my_amax = abs_max(my_amax, A[i][j], B[i][j]); 
      #pragma omp critical 
      { 
       if(fabs(amax)<fabs(my_amax)) 
        amax=my_amax; 
      } 
     } 
    } 
} 

И

for (i=0; i<MATRIX_DIM; i++) { 
    #pragma omp parallel firstprivate(my_amax) 
    { 
     #pragma omp for 
     for (j=0; j<MATRIX_DIM; j++) { 
      my_amax = abs_max(my_amax, A[i][j], B[i][j]); 
      #pragma omp critical 
      { 
      if (fabs(amax)<fabs(my_amax)) 
       amax=my_amax; 
      } 
     } 
    } 
} 

Единственное различие в коде положение параллельной части. Первый код всегда дает мне ошибку сегментации, а второй - отлично. Почему это так?

Я знаю, что #pragam omp parallel порождает необходимые темы, но так как следующий i цикл не объявлен как параллельно, это не должно быть проблемой, т.е. i часть должна получить выполняются последовательно в то время как j итераций, которые на самом деле распараллеленные будет выполнять в параллели. Что именно происходит в первом случае с итерациями i?

+0

Почему вы осуществляете максимальное сокращение вручную? OpenMP поддерживает сокращения (и реализация, вероятно, умнее ваших ...) –

+0

Если вы собираетесь использовать min/max by] hand (например, для OpenMP 2.0 с MSVC), то, по крайней мере, создавайте частные значения min/max для каждого потока и использовать только критические для каждого потока, а не для каждой итерации. –

+0

@JimCownie Это хороший вопрос, я тоже спросил себя. Но если вы хотите, чтобы это было кроссплатформенное решение, это нужно сделать вручную, поскольку MVSC не поддерживает предложения о сокращении min/max ... (Даже не в Visual Studio 15 или mvsc14 ...) –

ответ

2

Для того, что я вижу, вы забыли объявить i частным в первом случае. Поэтому i обновляется довольно случайным образом различными потоками, выполняющими соответствующий цикл, что приводит к отсутствию связанного доступа к массивам A и B.

Попробуйте добавить private(i) в свою директиву #pragma omp parallel firstprivate(my_amax) и посмотреть, что произойдет.

+0

Да, это сработало. Тем не менее, я никогда не утверждал, что цикл i выполняется параллельно. До этого момента я только спросил, породил необходимое количество потоков. Не будет ли я исполняться серийно в этом случае? – Tushar

+2

Да и нет: цикл 'i' находится внутри секции' parallel', он выполняется всеми потоками. Тем не менее, поскольку директива 'omp for' отсутствует, работа не разделяется потоками, а итерация не распространяется. Таким образом, все потоки повторяются на протяжении всего цикла 'i' итераций. – Gilles

Смежные вопросы