Эффективное 2D БПФ на реальных входных данных? - PullRequest
6 голосов
/ 18 октября 2010

В настоящее время я реализую двумерное БПФ для реальных входных данных, используя opencl (точнее, быструю двумерную свертку с использованием БПФ, поэтому мне нужно только то, что ведет себя аналогично, чтобы применить к нему свертку).2D БПФ реализован с использованием 1D БПФ на строках, а затем 1D БПФ на столбцах.

Чтобы сделать это более эффективным, я пытаюсь использовать симметрии БПФ с реальным вводом, чтобы иметь возможностьрассчитать меньшие БПФ.Я обнаружил, что могу объединить две строки в одну, используя первую в качестве реального компонента, вторую в качестве мнимого компонента, выполнить первое 1D БПФ для результирующей строки и затем использовать свойства симметрии для построения результатов 1D БПФ индивидуальногостроки из этого.Итак, в основном я делаю следующее:

Позвольте f и g быть строками из матрицы.

  1. Construct x = f + i * g
  2. Преобразование для получения F(x) = F(f) + i * F(g)
  3. Используйте симметрии для извлечения F(f) и F(g) из F(x)

Однако я не могу просто ввести результаты непосредственно во 2-й 1DБПФ, потому что в этом случае я бы преобразовал не всю матрицу, а две подматрицы.Однако извлечение данных между преобразованиями означает либо сохранение большего количества данных (n/2+1 записей, необходимых для выражения результата 1D БПФ на реальном вводе), либо объединение элементов с индексами 0 и индексом n/2 в один элемент (объединение с использованиемодин и тот же трюк, поскольку оба числа гарантированно являются действительными) и используют одинаковый объем памяти, но в моей свертке я должен сделать особый аргумент для этого.

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

Поэтому мой вопрос: есть лиэлегантный подход к этой проблеме, то есть такой, который будет работать без использования большего количества памяти или особых случаев для определенных элементов?

В идеале я хотел бы иметь возможность выполнять полное БПФ, не разбивая мои объединенные данные в серединеБПФ, но я не уверен, что это возможно.

1 Ответ

2 голосов
/ 20 октября 2010

Хммм ... две мои ссылки:

http://www.engineeringproductivitytools.com/stuff/T0001/PT10.HTM http://images.apple.com/acg/pdf/FFTapps_20090909.pdf

Я думаю, что фиксация в "эрмитовой" структуре данных со значениями 0 и n / 2упакованный в первый элемент способ идти вперед, так как прямая / обратная и эрмитова структуры будут работать лучше(x))) = rFFT (x), и riFFT может работать с «эрмитовым» массивом, создавая пару массивов Even и Odd, что снова дает исходную структуру.

Существуют и другие выборки, в которых исходный массив разбивается на 4 n / 2xn / 2 массива с корнями в (0,0), (0,1), (1,0).), (1,1), а затем завершились в конце, используя последний проход radix-4 ... возможно, это лучше для памяти GPU ... Я не знаю.

alan

...