Как попросить OpenMP создавать потоки только один раз при каждом запуске программы? - PullRequest
2 голосов
/ 15 ноября 2011

Я пытаюсь распараллелить большую программу, написанную сторонним разработчиком.Я не могу раскрыть код, но я постараюсь привести наиболее близкий пример того, что я хочу сделать.На основании кода ниже.Как вы можете видеть, поскольку предложение «параллельный» находится внутри цикла while, создание / уничтожение потоков выполняется (и выполняется) с каждой итерацией, что является дорогостоящим.Учитывая, что я не могу переместить инициализаторы ... и т. Д., Чтобы они были вне цикла while.

- Базовый код

void funcPiece0()
{
    // many lines and branches of code
}


void funcPiece1()
{
    // also many lines and branches of code
}

void funcCore()
{
    funcInitThis();
    funcInitThat();

#pragma omp parallel
    {
#pragma omp sections
        {
#pragma omp section
            {
                funcPiece0();
            }//omp section
#pragma omp section
            {
                funcPiece1();
            }//omp section
        }//omp sections
    }//omp parallel

}

int main()
{

    funcInitThis();
    funcInitThat();
#pragma omp parallel
    {
    while(1)
    {
        funcCore();
    }
    }

}

Я стараюсь избегать созданияуничтожение за итерацию, и сделать это один раз в начале / конце программы.Я перепробовал множество вариантов смещения «параллельного» предложения.То, что у меня в основном та же сущность, заключается в следующем: (ТОЛЬКО ОДНО создание / удаление потока для каждой программы) - То, что я пытался, но не смог «незаконный доступ» в инициализирующих функциях.-

Любая помощь будет принята с благодарностью!Спасибо!

Ответы [ 2 ]

2 голосов
/ 15 ноября 2011

OpenMP только создает рабочий поток при запуске. Параллельная прагма не порождает поток. Как вы определяете, что нить порождена?

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

Это можно сделать! Ключевым моментом здесь является перемещение цикла внутри одной параллельной секции и проверка того, что все, что используется для определения повторения или нет, все потоки примут абсолютно одинаковое решение. Я использовал общие переменные и выполняю синхронизацию непосредственно перед проверкой условия цикла.

Итак, этот код:

initialize();
while (some_condition) {
  #pragma omp parallel
  {
     some_parallel_work();
  }
}

можно преобразовать во что-то вроде этого:

#pragma omp parallel
{
  #pragma omp single
  {
    initialize();  //if initialization cannot be parallelized
  }
  while (some_condition_using_shared_variable) {
    some_parallel_work();
    update_some_condition_using_shared_variable();
    #pragma omp flush
  }
}

Самое главное - быть уверенным, что каждый поток принимает одно и то же решение в одних и тех же точках вашего кода.

Как заключительная мысль, по сути, то, что человек делает, это тратит накладные расходы на создание / уничтожение потоков (каждый раз, когда раздел #pragma omp parallel начинается / заканчивается) на накладные расходы на синхронизацию для принятия решений потоками. Я думаю, что синхронизация должна быть быстрее, однако здесь есть несколько параметров, которые могут быть не всегда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...