#multithreading #parallel-processing #openmp
#многопоточность #параллельная обработка #openmp
Вопрос:
У меня проблема с параллельным кодом цикла for в OpenMP, результат параллельного цикла for отличается от последовательного цикла for. Как сделать этот код параллельным с тем же результатом, что и последовательный код.
counter = 0;
#pragma omp parallel for
for(i=0; i<L; i ) {
int sum_found = 0;
for(j=0; j<M; j ) {
int found = 0;
for(k=0; k<N_SUBSET; k ) {
if (i==0 amp;amp; unsorted_arr[j*N_SUBSET k] < intervals[i]) {
s_prime[counter] = unsorted_arr[j*N_SUBSET k];
counter ;
found ;
}
else if (i!=0 amp;amp; unsorted_arr[j*N_SUBSET k] >= intervals[i-1] amp;amp; unsorted_arr[j*N_SUBSET k] < intervals[i]) {
s_prime[counter] = unsorted_arr[j*N_SUBSET k];
counter ;
found ;
}
else if (i==L-1 amp;amp; unsorted_arr[j*N_SUBSET k] >= intervals[i-1]) {
s_prime[counter] = unsorted_arr[j*N_SUBSET k];
counter ;
found ;
}
}
C[i][j] = found;
sum_found = found;
}
n_intervals_len[i] = sum_found;
}
Комментарии:
1. Вы пробовали компилировать с включенной обработкой потоков?
2. Я просто компилирую с помощью GCC и OpenMP
3. Попробуйте добавить
-fsanitize=thread
. Он сообщит вам, есть ли у вас скачок данных и где он происходит
Ответ №1:
Поскольку часть контекста приведенного выше кода отсутствует (особенно объявления переменных), довольно сложно сказать, что происходит не так. Но вот несколько идей:
-
счетчики цикла j и k должны быть объявлены закрытыми, потому что в противном случае у вас может возникнуть состояние гонки для них
-
операторы
counter
иfound
также выполняют запросы на обновления из разных потоков для одной и той же переменной. Вам придется либо использоватьatomic
конструкцию для них, либо использовать надлежащее сокращение OpenMP, чтобы избавиться от состояния гонки.