2017-02-10 12 views
1

У меня есть реализация цифрового бесселевого фильтра, который является узким местом производительности для моей программы. Я хотел бы распараллелить основной цикл с помощью OpenMP.Параллельный цикл с использованием OpenMP, когда итерации цикла не являются независимыми

Функция принимает входной массив paddedsignal и массивы коэффициентов фильтра dcof и ccof и производит временный массив temp который фильтруют. Основной цикл этого процесса выглядит следующим образом:

for (i=order; i<end; i++) 
    { 
     temp[i] = ccof[0]*paddedsignal[i]; 
     for (p=1; p<=order; p++) 
     { 
      temp[i] += ccof[p]*paddedsignal[i-p] - dcof[p]*temp[i-p]; 
     } 
    } 

В частности, обратите внимание, что значение temp[i] зависит от предыдущих значений temp[i-p]. Это смешивает простую директиву #pragma omp for, так как значение temp[i] вблизи границ между разделами массива, которое будет обрабатываться разными потоками, будет иметь проблемы с состоянием гонки. В основном, если поток 1 принимает индексы между 0-99, а поток 2 принимает 100-199, значение в 100 будет неправильным, так как оно будет вычислено до значения в 99, от которого это зависит.

Есть ли способ спасти эту ситуацию? Я отчаиваюсь относительно того, что я могу сделать, чтобы распараллелить это, поскольку тот факт, что отфильтрованные значения зависят от соседних значений, делает его по сути серийным вычислением. Есть ли способ обойти это?

+1

Это серийный расчет. Единственный способ ускорить его работу - получить более быстрый процессор. Альтернативой может быть использование другого типа фильтра, который более поддается параллельному исполнению. Или, если данные, которые нужно отфильтровать, могут быть выгружены каким-то образом, у вас есть разные партии, которые фильтруются разными потоками. – bazza

+0

Я думаю, что пакетная фильтрация будет способ пойти – KBriggs

+1

Внутренний цикл может быть как [префикс сумма как проблема] (http://stackoverflow.com/a/35840595/2542702)? –

ответ

1

В основном вы не можете распараллелить внешний цикл из-за зависимости, которую вы правильно идентифицируете.

Вы можете распараллелить внутренний цикл с уменьшением. Но это было бы полезно только для больших order, и даже тогда, возможно, просто приведет к ложному обмену, потому что данные перетасовываются. Можно было бы попытаться усложнить данные, чтобы чередовать signal и temp среди потоков, что потребовало бы сортировки конструкции совместного использования вручную. Я сомневаюсь, что это того стоит, так как сокращение приведет к увеличению накладных расходов.

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

+0

Это более или менее мой вывод. Мне придется искать в другом месте для более естественного места для распараллеливания. Код уже реализует стратегию фильтрации блоков, которая обертывает эту функцию, поэтому, вероятно, это более естественное место для этого. – KBriggs

0

Возможно, вы ищете #pragma omp для заказа . Он выполняет код в том же порядке, в котором он будет выполняться последовательно

Но имейте в виду:

  • могут быть использованы только в динамическом экстента для директивы
  • очень «дорого» (вполне вероятно, что ваше убыстрение не будет столь же хорошо, как вы могли бы подумать)

Для получения дополнительной информации см: omp ordered

+0

Какой смысл форсировать серийное исполнение многопоточным способом? Где будет ускорение? – KBriggs

+0

, честно говоря, я никогда не использовал эту директиву, поскольку использую многопоточность только тогда, когда у меня есть независимая работа (в отличие от вашего примера). Но я помню, что в некоторых случаях это полезно для последовательного ввода-вывода проекта-партнера. Если вы хотите получить дополнительную информацию об упорядоченном предложении: http://stackoverflow.com/questions/13224155/how-does-the-omp-ordered-clause-work – QuickSort

+1

'приказ" только имеет смысл, если у вас есть значительная часть итерации, которые не упорядочены. Для этого фильтра вам нужно будет заказать почти весь корпус цикла, по существу, сериализуя все. – Zulan

 Смежные вопросы

  • Нет связанных вопросов^_^