LINUX.ORG.RU

Параллельный low-pass фильтр для GPU

 


0

2

Пытаюсь освоить OpenCL, и всё больше мне кажется, что это сферическая технология в вакууме. Например, я нашел алгоритмы reduce и scan для ассоциативных функций. Мне же хочется посчитать такой массив (по сути, простейший low-pass фильтр):

b_{0} = a_{0}
b_{n} = \alpha b_{n-1} + (1-\alpha) a_{n}

Найденный мной алгоритм scan делает из массива (a0, a1, a2, a3, ...) массив (i, a0, a0+a1, a0+a1+a2, ...) где + — ассоциативная функция от 2-х аргументов, i+x = x

Только вот функция f(x,y) = a*x + (1-a)*y нифига не ассоциативная. И что, нет совершенно никакого способа посчитать массив b на GPU?

Low-pass фильтр взял совершенно наобум, но потребность считать что-то, что зависит от предыдущего шага вполне естественна. Например, решение дифуров методом Эйлера (Рунге-Кутта, да кого угодно) тоже предполагает такие вычисления

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

tim239 ★★
()

Нет времени объяснять, нужно рекламировать модную параллельность.

anonymous
()
Ответ на: комментарий от tim239

В сети же есть какие-то страшные библиотеки, которые считают на GPU и дифуры, и фильтры, и черта с рогами. А описания алгоритма вменяемого нигде нет.

anonymous
()
Ответ на: комментарий от anonymous

Они могут на gpu запускать только ту часть алгоритма, которая неплохо параллелится. А в данном случае если a и b лежат в памяти хоста то последовательно выполнить над каждым элементом два умножения и одно сложение за пару тактов процессора будет быстрее чем пересылать на gpu и обратно.

tim239 ★★
()

конкретно этот пример можно распараллелить, развернув b до функции от b[0], и дальше надо играться с scan для суммирования термов не зависящих от b[0], alpha в степени возводить (несомненно проблемы с точностью), делать несколько ядер и аллоцировать промежуточные буферы - в общем очень муторно, не факт что что-то ускорит, но теоретически (кажется) возможно. ну и иллюстрация, как изощрённо бывает распараллеливание, особенно под гпу..

anonymous
()

В твоем случае никак не распараллелишь. А вот если бы ты захотел, скажем, скользящую медиану (или тупо скользящее среднее) посчитать, то распараллелить можно: делишь всю область на N кусков, считаешь в каждой области, а затем (опять же, параллельно) обрабатываешь стыки.

Очень много алгоритмов обработки изображений параллелизуют именно так. Скажем, нужно тебе найти дофига объектов на большом изображении. Бинаризуешь его по определенному признаку, а затем делишь на N кусков. В параллели для всех кусков происходит поиск n-связных областей; но дальше все равно придется состыковать куски (с объединением соседних n-связных областей) и провести процедуру перенумерации.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.