Вопрос:

OpenMP - Управление несколькими вызовами для блокировки с параллельным для

c++ multithreading openmp

47 просмотра

1 ответ

516 Репутация автора

Допустим, у меня есть программа с вызванной функцией run(), эта функция будет for loopвыполнять некоторые действия внутри нее.

Так как я хочу , чтобы воспользоваться всеми своими процессорными ядрами, я использую OpenMPс #pragma omp parallel forраспараллелить его.

Теперь проблема в том, что эта run()функция вызывается из нескольких потоков, и когда одновременно вызывается большое количество потоков run(), у меня огромное снижение производительности, так как OpenMP threadsот каждого parallel forвызова pragma будет много .

Просто ilustrate, у меня есть нить Aи нить Bи мой процессор имеет 4 ядра, поток Aвызывает функцию , run()которая будет создавать 4 OpenMPпотоков для выполнения for loop.

Теперь, в то же самое время, поток Bтакже вызывает run(), это сгенерирует больше 4 OpenMPпотоков, в результате чего в общей сложности будет 8 OpenMPпотоков.

Мой вопрос: есть ли какой-то способ сбалансировать это с тем OpenMP, чтобы в приведенном выше примере OpenMPможно было использовать половину потоков для Aи половину для B. Другой стратегией было бы OpenMPсоздание очереди потоков, поэтому она никогда не использует более 4 OpenMPпотоков.

Возможно ли что-то подобное?

PS. Обратите внимание, что 2 потока в моем примере просто иллюстрируют это, в моей программе неясно, сколько потоков будет вызываться, run()так как количество потоков создается во время выполнения по мере необходимости.

PS 2. Обратите внимание, что всякий раз, когда я говорю о OpenMPсозданных потоках, я называю это OpenMPпотоком, а когда я говорю о потоке, созданном другими средствами ( std::threadнапример), я называю его просто потоком.

Автор: Sassa Источник Размещён: 08.11.2017 10:53

Ответы (1)


0 плюса

1173 Репутация автора

Если вы используете только OpenMP для параллелизма и у вас включен вложенный параллелизм, вы можете использовать num_threadsаргумент для, pragma omp parallelчтобы указать использование половины потоков:

int const currentNumThreads = omp_get_num_threads();
int const maxNumThreads = omp_get_max_num_threads();
#pragma omp parallel for num_threads(maxNumThreads/currentNumThreads)
for ( ... ) {
   ...
}

Даже если вы используете смешанные технологии многопоточности (что, похоже, так и есть), вы все равно можете добиться того же, используя различные методы для установки currentNumThreadsи maxNumThreads.

Слово предостережения, хотя. Использование вложенного параллелизма обычно не рекомендуется для OpenMP, так как делает код довольно хрупким и жестким . Любые изменения в вашей run()функции должны знать, откуда она вызывается, и любые будущие вызовы run()должны знать, что внутри нее. И с точки зрения производительности, и с точки зрения обслуживания лучше всего использовать параллельный подход к данным для использования OpenMP. То есть, выполнить аналогичный набор операций в каждом потоке, но на разных порциях данных.

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

Автор: dlasalle Размещён: 08.11.2017 11:39
Вопросы из категории :
32x32