Ответ 1
Прежде всего, наиболее общий способ выражения кода:
#pragma omp parallel for schedule(dynamic)
for (int i = 0; i < jobs; ++i)
{
}
Предположим, что реализация имеет хороший дефолт.
Прежде чем идти дальше, измерьте. Конечно, иногда это может быть необходимо, чтобы помочь в реализации, но не делайте этого вслепую. Большинство других вещей зависят от реализации, поэтому просмотр стандарта не очень помогает вам.
Если вы по-прежнему вручную укажете количество потоков, вы также можете указать std::max(N, jobs)
.
Вот некоторые вещи, которые можно посмотреть, которые могут повлиять на производительность в вашем случае:
- Не стоит слишком беспокоиться о том, чтобы набросать ненужные потоки. Реализации смягчают это пулами потоков. Это не значит, что он всегда идеален - так измеряйте.
- Не переписывайте, если вы не знаете, что делаете. Используйте максимальное количество нитей сердечника. Это общий совет.
- Значение
OMP_WAIT_POLICY
имеет значение в вашем случае, поскольку оно определяет, как ведут себя потоки ожиданий. В вашем случае избыточные потоки будут ждать неявного барьера в конце параллельной области. Реализации могут делать то, что им нужно, с настройкой, но вы можете предположить, что сactive
потоки используют некоторую форму ожидания и сpassive
потоками будут спать. Ожидаемый поток занятости может использовать ресурсы вычислительных потоков, например, бюджет мощности, который может использоваться для увеличения частоты турбо-потоков вычислительных потоков. Также они теряют энергию. В случае переподписки воздействие активных потоков намного хуже.