Я пытаюсь выполнить код 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
?
Почему вы осуществляете максимальное сокращение вручную? OpenMP поддерживает сокращения (и реализация, вероятно, умнее ваших ...) –
Если вы собираетесь использовать min/max by] hand (например, для OpenMP 2.0 с MSVC), то, по крайней мере, создавайте частные значения min/max для каждого потока и использовать только критические для каждого потока, а не для каждой итерации. –
@JimCownie Это хороший вопрос, я тоже спросил себя. Но если вы хотите, чтобы это было кроссплатформенное решение, это нужно сделать вручную, поскольку MVSC не поддерживает предложения о сокращении min/max ... (Даже не в Visual Studio 15 или mvsc14 ...) –