Я распараллелил свертку изображений и факторизацию lu, используя OpenMP и Intel TBB. Тестирую на 1-8 ядрах. Но когда я пробую это на 1 ядре в OPenMP и TBB, указав один поток, например, с помощью set_num_threads(1) и task_scheduler_init InitTBB(1) соответственно; Производительность TBB показывает небольшое ухудшение по сравнению с последовательным кодом из-за накладных расходов TBB, но, что удивительно, OpenMP не показывает никаких накладных расходов на одном ядре и работает точно так же, как последовательный код (с использованием уровня оптимизации Intel O3). Я использую статическое планирование циклов OpenMP. Это реально или я делаю какую-то ошибку?
Накладные расходы OpenMP
Ответы (4)
Среда выполнения OpenMP, вероятно, не создаст никаких потоков, если вы запустите ее только с одним потоком.
Кроме того, простое использование директив параллелизации OpenMP иногда ускоряет выполнение последовательного кода, поскольку вы, по сути, предоставляете компилятору больше информации. Например, конструкция разделения работы сообщает компилятору, что итерации цикла независимы друг от друга, что он, возможно, не смог бы вывести самостоятельно и что позволяет компилятору использовать более агрессивные стратегии оптимизации. Не всегда, конечно, но я видел, как это происходит с «реальным кодом».
OpenMP — это то, где всю работу делает компилятор. Если компилятор всегда знает, что это будет последовательный код, он вполне законно может пропустить все параллельные биты.
TBB, насколько я понимаю, это просто библиотека. Алгоритм всегда нужно будет дополнить необходимыми частями, чтобы запускать его как параллельно, так и последовательно.
OpenMP разветвляет декорированную часть (#pragma omg for/parallel) кода на основной поток (который также будет выполняться без OpenMP) и дополнительные потоки.
Если вы настроите использование только одного потока, то это будет только основной поток, который будет выполняться без директивы OpenMP. Накладных расходов нет, потому что путь выполнения не был разветвлен.
Суть OpenMP в том, что компилятор делает всю работу за вас, требует минимальной модификации последовательного кода и часто дает хорошие результаты, если задачи, поставленные перед каждым потоком, довольно велики. Я бы посоветовал попробовать протестировать ваш код с помощью Pthread или thread на С++ 11 и посмотреть результаты.
num_threads
доset_num_threads(num_threads)
известен только во время выполнения, то есть из пользовательского ввода? - person Walter   schedule 20.03.2013