Я создал код на C ++, не думая, что позже у меня возникнет необходимость в его многопоточности. Я сейчас многопоточным 3 основных цикла для openMP. Вот сравнение производительности (как измерено с time
из баш)
Одиночная нить
real 5m50.008s
user 5m49.072s
sys 0m0.877s
Многопоточный (24 потока)
real 1m22.572s
user 28m28.206s
sys 0m4.170s
Использование 24 ядер сократило реальное время в 4,24 раза. Конечно, я не ожидал, что код будет в 24 раза быстрее. Я действительно не знал, чего ожидать на самом деле.
— Существует ли эмпирическое правило, позволяющее прогнозировать, насколько быстрее будет выполняться данный код n
темы по сравнению с одной нитью?
— Есть ли общие советы по улучшению производительности многопоточных процессов?
Я уверен, что вы знаете о очевидном, как стоимость барьеров. Но трудно провести грань между тем, что тривиально, и тем, что может быть полезным для кого-то. Вот несколько уроков, извлеченных из использования, если я больше подумаю, я добавлю их:
Всегда старайтесь использовать частные переменные потока как можно дольше, учтите, что даже для сокращений, обеспечивающих лишь небольшое количество коллективных результатов.
Предпочитают параллельные участки длинных участков кода и длинных параллельных участков (#pragma omp parallel ... #pragma omp for
) вместо распараллеливания циклов отдельно (#pragma omp parallel for
).
Не распараллеливайте короткие циклы. В двумерной итерации часто достаточно распараллелить внешний цикл. Если вы делаете распараллеливание всего этого, используя collapse
Имейте в виду, что OpenMP будет линеаризовать его, вводя переменную слияния и доступ к индексам по отдельности влечет за собой дополнительные расходы
Используй нити приватных куч. Избегайте совместного использования пулов и коллекций, если это возможно, даже если разные члены коллекции будут доступны независимо от разных потоков.
Профилируйте свой код и посмотрите, сколько времени уходит на занятые ожидания и где это может происходить.
Изучите последствия использования различных стратегий графика. Попробуйте что лучше, не думайте.
Если вы используете критические разделы, назовите их. Все безымянные CS должны ждать друг друга.
Если в вашем коде используются случайные числа, сделайте его воспроизводимым: определите локальные потоки RNG, запустите все контролируемым образом, наведите порядок сокращений. Ориентир детерминированно, а не статистически.
Просмотрите похожие вопросы о переполнении стека, например, прекрасные ответы Вот.
Других решений пока нет …