Модель потребитель-производитель с OpenMP - PullRequest
0 голосов
/ 29 ноября 2011

Я пытаюсь реализовать модель с одним производителем и несколькими потребителями, используя OpenMP (я знаю, что я мог бы также пойти на потоки повышения, которые могли бы быть более подходящими). ​​

Вот мой код, который довольно прост и использует тип очереди с поддержкой потоков:

bool producer_finished = false;

#pragma omp parallel default( none ) shared( producer_finished, buffer, datagen )
{
    #pragma omp sections
    {
        #pragma omp section
        { // single producer

            while( datagen ) {
                DType data = datagen.next()
                buffer.push( data );
            }

            producer_finished = true;
            #pragma omp flush( producer_finished )

        } // end omp section

        #pragma omp section
        {
            #pragma omp for schedule( static, 1 )
            for ( int i = 0; i < omp_get_max_threads() - 1; ++i ) {

                while ( ! producer_finished ) {

                    #pragma omp critical( buffer )
                    {
                        DType = buffer.pop();
                    }

                    processData( data );
                    outputData( data );

                    #pragma omp flush( producer_finished )
                }
            } // end omp for
        } // end omp section

    } //end omp sections
} // end omp parallel

Проблема здесь в том, что производитель запускает и отправляет данные до тех пор, пока буфер не будет заполнен, но потребители никогда не начнут. Если я удаляю раздел вокруг «для прагмы», то же самое происходит. Вы видите, что не так с моим подходом?

Я также получаю это предупреждение во время компиляции:

warning: work-sharing region may not be closely nested inside of work-sharing, critical, ordered or master region

Это относится к вложенности цикла for в разделе. Как правильно сделать это в этом случае?

Спасибо за ваш отзыв.

Редактировать: Только что найдено этот связанный вопрос , set_omp_nested (1) мне не помогает. Я постараюсь поместить его в отдельные функции ...

Ответы [ 4 ]

0 голосов
/ 06 ноября 2017

Извлеките весь #pragma omp для в функцию и измените его на #pragma omg параллельный для.

перед выполнением текущей параллельной #pragma omp активируйте вложенный параллелизм с помощью omp_set_nested (1).

0 голосов
/ 07 февраля 2012

ваш код OpenMP синтаксически неверен.Это то, что говорит вам компилятор.Параллельная секция и параллельная петля - обе конструкции совместного использования, и они не могут быть вложены друг в друга.Вы можете добавить внутренний параллельный цикл вокруг конструкции for и, таким образом, использовать вложенный параллелизм, который вам может потребоваться явно включить.

Кроме того, использование директивы flush недостаточно.Вам также необходимо синхронизировать данные, с которыми вы работаете.Настоятельно рекомендуется использовать flush без списка - если вообще.

Вы можете задать вопросы, связанные с OpenMp, на форуме www.openmp.org, чтобы поговорить с выражателями OpenMP.

С наилучшими пожеланиями, Дитер

0 голосов
/ 07 февраля 2012

См. Пример правильного использования flush в спецификации OpenMP V3.0 , приложение A.21.

0 голосов
/ 30 ноября 2011

OpenMP предназначен для параллельных вычислений, это не универсальная библиотека потоков.Поэтому попытка сделать цикл производитель / потребитель с OpenMP просто использует неправильный инструмент, ИМХО.

...