Почему моя реализация OpenMP медленнее, чем реализация с одним потоком?

Я изучаю параллелизм OpenMP и пробовал свои силы в имеющемся у меня коде. В этом коде я попытался сделать все циклы for параллельными. Однако это, кажется, делает программу НАМНОГО медленнее, по крайней мере, в 10 раз медленнее или даже больше, чем однопоточная версия.

Вот код: http://pastebin.com/zyLzuWU2

Я также использовал pthreads, которые оказались быстрее, чем однопоточная версия.

Теперь вопрос в том, что я делаю неправильно в своей реализации OpenMP, что вызывает это замедление?

Спасибо!

редактировать: однопоточная версия - это просто версия без всех #pragmas


person nubela    schedule 18.02.2011    source источник
comment
Вы используете его на одноядерной системе?   -  person nmichaels    schedule 18.02.2011
comment
если вы не используете не более 1 потока на ядро, они, вероятно, будут конкурировать друг с другом за общие ресурсы. Внедрение параллелизма автоматически не ускоряет работу программ.   -  person Matt Ball    schedule 18.02.2011
comment
@matt: возможно, вы можете написать ответ об этом и, возможно, некоторые предложения по обходному пути? Благодарность!   -  person nubela    schedule 18.02.2011
comment
В вашем коде есть прагмы, которые неверны и игнорируются, но вы должны понимать концепции OpenMP. Прагмы, о которых я говорю, — это конец #pragma omp. Прагмы OpenMP применяются к структурированным блокам в C/C++ и поэтому не нуждаются в конечной прагме. Только в Fortran, где у вас нет обозначенного блока ({}), вам нужно использовать конечные директивы.   -  person ejd    schedule 18.02.2011


Ответы (3)


Одна проблема, которую я вижу в вашем коде, заключается в том, что вы используете OpenMP в очень маленьких циклах (например, 8 или 64 итерации). Это будет неэффективно из-за накладных расходов. Если вы хотите использовать OpenMP для решения проблемы с n ферзями, посмотрите задачи OpenMP 3.0 и параллелизм потоков для решения задач с ветвями и границами.

person Jeremiah Willcock    schedule 18.02.2011
comment
Задача требует, чтобы вы посмотрели на то, как вы распараллеливаете по-разному. Тем не менее, в Интернете есть несколько статей и презентаций, демонстрирующих почти линейное ускорение (2 потока в два раза быстрее последовательного, 4 потока почти в 4 раза быстрее последовательного и т. д.) при использовании задач OpenMP для распараллеливания задачи nqueens. - person ejd; 18.02.2011

Я думаю, что ваш код слишком сложен, чтобы рассматривать его здесь. Одна ошибка, которую я увидел сразу, заключается в том, что это даже не правильно. В местах, где вы используете omp parallel for для суммирования, вы должны использовать reduction(+: yourcountervariable), чтобы правильно собрать результаты различных потоков. В противном случае один поток может перезаписать результат других.

person Jens Gustedt    schedule 18.02.2011
comment
Правильным предложением является сокращение (+: yourCounterVariable). Без этого или использования атомарных, критических или блокировок ваши результаты даже не будут правильными. - person ejd; 18.02.2011

Как минимум две причины:

  1. Вы делаете только 8 итераций очень простого цикла. Ваша среда выполнения будет полностью зависеть от накладных расходов, связанных с настройкой всех потоков.

  2. В некоторых местах раздел critical может вызвать разногласия; все потоки будут постоянно пытаться получить доступ к критической секции и блокировать друг друга.

person Oliver Charlesworth    schedule 18.02.2011