OpenMp: как убедиться, что каждый поток работает по крайней мере за 1 итерацию в динамическом планировании c - PullRequest
0 голосов
/ 29 февраля 2020

Я использую динамическое планирование c для итерации l oop. Но когда работы в каждой итерации слишком малы, некоторые потоки не работают или когда имеется огромное количество потоков. Например. Есть 100 итераций и 90 потоков, я хочу, чтобы каждый поток выполнял хотя бы одну итерацию, а остальные 10 итераций можно распределить потокам, которые выполнили свою работу. Как я могу это сделать?

1 Ответ

2 голосов
/ 29 февраля 2020

Вы не можете заставить OpenMP выполнить это. Тем не менее, вы можете дать подсказки для среды выполнения OpenMP, так что она, вероятно, сделает это, когда (решит), что это возможно за счет более высоких издержек. По пути стоит указать гранулярность динамически запланированного l oop. Вот пример:

#pragma omp parallel for schedule(dynamic,1)
for(int i=0 ; i<100 ; ++i)
    compute(i);

При таком коде среда выполнения может свободно распределять работу между потоками (используя планировщик разделения работы) или позволить потокам украсть работу главного потока, который управляет параллельные вычисления (с использованием планировщика кражи работ). Во втором подходе, хотя степень детализации составляет 1 л oop итераций, некоторые потоки могут украсть больше работы, чем им действительно нужно (например, до , как правило, , повышение производительности). Если итерации l oop достаточно быстрые, работа, вероятно, не будет сбалансирована между потоками.

Создание 90 потоков является дорогостоящим, а отправка работы в 90 потоков также далеко не бесплатна, поскольку в основном ограничена относительно высокая задержка операций atomi c, их реализуемость, а также задержка бодрствующих потоков. Более того, хотя такая операция представляется синхронной с точки зрения пользователя, на практике это не так (особенно с 90 потоками и в многосокетных архитектурах на основе NUMA). В результате некоторые потоки могут закончить sh, чтобы вычислить одну итерацию l oop, в то время как другие могут не знать о параллельных вычислениях или даже не создавать их. Затраты на информирование потоков о выполняемых вычислениях обычно увеличиваются по мере увеличения количества используемых потоков. В некоторых случаях эти издержки могут быть выше, чем фактические вычисления, и может быть более эффективным использование меньшего количества потоков.

Разработчикам среды выполнения OpenMP иногда следует соблюдать балансировку работы с меньшими накладными расходами на связь. Таким образом, эти решения могут плохо работать в вашем случае, но могут улучшить работоспособность других видов приложений. Это особенно верно для планировщика кражи работ (например, Clang / I CC OpenMP runtime). Обратите внимание, что улучшение масштабируемости сред времени выполнения OpenMP является областью непрерывных исследований.

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

Обновление

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

Например, если у вас процессор с 8 аппаратные потоки, и вы используете 8 потоков OpenMP, вы можете примерно предположить, что они будут работать одновременно. Но если вы используете 16 потоков OpenMP, ваша операционная система может планировать их следующим образом:

  • первые 8 потоков выполняются в течение 100 мс;
  • последние 8 потоков выполняются в течение 100 мс;
  • первые 8 потоков выполняются снова в течение 100 мс;
  • последние 8 потоков выполняются снова в течение 100 мс;
  • et c .

Если ваше вычисление длится менее 100 мс, динамические / управляемые планировщики OpenMP переместят работу 8 последних потоков в 8 первых потоков, чтобы общее время выполнения было быстрее. Следовательно, 8 первых потоков могут выполнять всю работу, а 8 последних потоков не будут иметь ничего, что нужно выполнить один раз. Это является причиной дисбаланса между потоками.

Таким образом, если вы хотите измерить производительность программы OpenMP, вы НЕ должны использовать больше потоков OpenMP, чем аппаратных потоков (если вы не точно знаю, что вы делаете, и вы полностью осведомлены о таких эффектах).

...