Правильный способ переопределения минимальных / максимальных сокращений OpenMP с помощью сброса

Несколько дней назад мне пришло в голову, что фрагмент кода для реализации минимального / максимального сокращения OpenMP, который я использовал довольно часто, может на самом деле быть неправильным:

В некоторых случаях, когда условие сокращения OpenMP min-max было недоступно (старая версия OpenMP) или мне также требовался индекс для максимального значения, я использовал код, подобный этому:

#pragma omp parallel private(myMax,myMax_idx) shared(globalMax,globalMax_idx)
{
    #pragma omp for
    for (...) {
    }

    if (myMax >= globalMax) {
        #pragma omp critical
        {
            if ((myMax > globalMax)||(myMax == globalMax && globalMax_idx < myMax_idx) {
                globalMax = myMax;
                globalMax_idx = myMax_idx;
            }
        }
    }
}

Теперь мне пришло в голову, что этот код может на самом деле давать неправильные результаты, потому что совместно используемая переменная НЕ означает, что все потоки обращаются к одной и той же части памяти, но они могут использовать личную копию, которая может быть устаревшей со всеми другими потоками. Так что мне нужно использовать #pragma omp flush синхронизировать переменную.

[...]
    #pragma omp flush(globalMax)
    if (myMax > globalMax) {
        #pragma omp critical
        {
            if (myMax > globalMax) globalMax = myMax;
        }
    }
[...]

В работе М. Сюсса и др. "Типичные ошибки в OpenMP и как их избежать" эта реализация описывается как

По сути это повторная реализация редукции с использованием оператора max.

Но мне интересно, верен ли этот фрагмент кода, потому что я не вижу, чтобы поток записи сбрасывал его версию globalMax в память.

Также в случае поиска по индексу мне нужно будет также сбросить globalMax_idx переменная. Правильно?

Этот вопрос отчасти связан с

Так что, если Код из "Типичных ошибок в OpenMP" предполагает, что критическая область сбрасывается, то стоит ли явно сбрасывать globalMaxпеременная перед if?

Какой код я должен использовать?

0 ответов

Другие вопросы по тегам