Я пытаюсь реализовать openMP, но, как и многие другие плакаты до меня, результатом было просто замедлить код. Вдохновленный предыдущими ответами, я перешел от использования #pragma omp parallel for
к #pragma omp task
в надежде, что смогу избежать некоторых накладных расходов. К сожалению, распараллеленный код все еще в два раза медленнее, чем последовательный. Из других ответов кажется, что правильная процедура зависит от конкретных требований кода, поэтому я подумал, что мне придется самому задать вопрос.
Сначала псевдокод:
#pragma omp parallel
{
#pragma omp master
while (will be run some hundreds of millions of times)
{
for (between 5 and 20 iterations)
{
#pragma omp task
(something)
}
#pragma omp taskwait <- it is important that all the above tasks are completed before going on
(something)
if (something)
{
(something)
for (between 50 and 200 iterations)
{
#pragma omp task
(something)
}
#pragma omp taskwait
(something)
}
}
}
Только два цикла for могут быть распараллелены, остальные должны быть выполнены в правильном порядке. Я придумал поместить параллельные и главные директивы вне цикла while, чтобы уменьшить накладные расходы на создание команды.
Мне также немного любопытно, правильно ли я использую taskwait - в спецификации говорится, что «родительская задача» приостановлена до тех пор, пока не будут выполнены все дочерние задачи, но не совсем ясно, применима ли здесь и эта терминология, где области задач не являются вложенными.
Может кто-нибудь придумать лучший способ использования openMP, чтобы я мог получить ускорение?
РЕДАКТИРОВАТЬ: каждый шаг в цикле while зависит от всех предыдущих шагов, и поэтому они должны выполняться последовательно, с обновлением в конце. Это реализация "алгоритма, управляемого событиями" для моделирования нейронных сетей, если кому-то интересно.