OpenMP num_threads (1) выполняется быстрее, чем без OpenMP - PullRequest
10 голосов
/ 26 мая 2010

Я запускал свой код в различных обстоятельствах, что привело к тому, что я считаю странным поведением. Я тестировал двухъядерный процессор Intel Xeon с HT.

Нет оператора OpenMP '#pragma', общее время выполнения = 507 секунд

С оператором OpenMP '#pragma', указывающим 1 ядро, общее время выполнения = 117 секунд

С оператором OpenMP '#pragma', указывающим 2 ядра, общее время выполнения = 150 секунд

С оператором OpenMP '#pragma', указывающим 3 ядра, общее время выполнения = 157 секунд

С оператором OpenMP '#pragma', указывающим 4 ядра, общее время выполнения = 144 секунды

Полагаю, я не могу понять, почему комментирование моей строки openmp заставляет программу так сильно замедляться между 1 потоком без openmp и 1 потоком с openmp.

Все, что я меняю, это между:

//#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1) schedule(guided)

and...

#pragma omp parallel for shared(segs) private(i, j, p_hough) num_threads(1,2,3,4) schedule(guided)

В любом случае, если кто-нибудь знает, почему это может происходить, пожалуйста, дайте мне знать!

Спасибо за любую помощь,

Brett

РЕДАКТИРОВАТЬ: я рассмотрю некоторые из комментариев здесь

Я использую num_threads (1), num_threads (2) и т. Д.

При дальнейшем исследовании выясняется, что мои результаты противоречивы в зависимости от того, включена ли в код строка «расписание (руководствуясь)».

-При использовании строки расписания (руководствуясь) я создаю самое быстрое решение независимо от количества потоков. -При использовании планировщика по умолчанию мои результаты значительно медленнее и разные значения -С улучшением графика (руководствуясь) не увеличивается с увеличенными потоками -Без графика (руководствуясь) я получаю улучшение с добавлением потоков

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

Похоже, что для моего итерационного цикла ~ 900, когда я использую расписание (управляемое), я обрабатываю только ~ 200 итераций, тогда как без расписания (управляемое) я обрабатываю все 900 итераций. Есть мысли?

1 Ответ

8 голосов
/ 14 марта 2011

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

Я думаю, что когда вы устанавливаете количество потоков в один (1), OpenMP просто вызывает процедуру для процедуры OpenMP, реализующей цикл, поэтому накладные расходы минимальны, а производительность практически идентична случаю без OpenMP ,

В противном случае, я думаю, что OpenMP устанавливает некоторые семафоры, и ожидающие «рабочие» потоки просыпаются, синхронизируют их доступ к структурам данных, сообщая им, какие параметры цикла устанавливать, и затем вызывают подпрограмму, которая выполняет работу, и когда они завершают кусок работы, они снова сигнализируют мастер поток. Эта синхронизация должна происходить для каждой части работы, выполняемой потоком, а затраты на синхронизацию нетривиальны.

Использование опции планирования STATIC может помочь уменьшить накладные расходы на планирование / синхронизацию, особенно если количество итераций цикла велико по сравнению с количеством ядер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...