У меня есть такой массив (0,0 внизу слева):
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 1 0 1 0 1 0 0
0 0 1 1 1 1 1 1 1
1 0 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1
Моя цель - получить индекс более высокой строки, которая не полностью установлена на 0
. Для этого я сделал код ниже (который отлично работает):
max=0;
for (i=0 ; i<width ; ++i) {
for (j=max ; j<height ; ++j) {
if (array[i*height+j]!=0) {
max=j;
}
}
}
Для второго цикла я инициализирую j
значением max, потому что глобальный максимум не может быть меньше локального максимума. И таким образом я могу уменьшить количество тестов.
Я попытался распараллелить это с OpenMp
. Мой код сейчас:
max=0;
#pragma omp parallel for default(none) \
shared(spec, width, height) \
collapse(2) \
reduction(max:max)
for (i=0 ; i<width ; ++i) {
for (j=max ; j<height ; ++j) {
if (array[i*height+j]!=0) {
max=j;
}
}
}
Что приводит к ошибке сегментации. Чтобы заставить его работать, я изменил j=max
на j=0
. Таким образом, проблема, похоже, связана с переменной max
.
Я не понимаю, почему, потому что при сокращении эта переменная должна быть приватной (или lastprivate) между каждым потоком. Так почему это приводит к сбою? И как я могу использовать свою «оптимизацию» с OpenMP?
max
внутри цикла, ваш код пытается сделать именно это. OpenMP требует, чтобы количество циклов вычислялось один раз в начале, чтобы можно было распределять итерации по потокам и не изменять их позже, иначе это нарушит планирование. - person High Performance Mark   schedule 18.06.2018collapse(1)
, и он тоже не работает, cppstudy объяснил, почему в этом ответе. Но вы породили важную вещь, которая может привести к другим проблемам, так что +1 вам;) - person Phantom   schedule 18.06.2018