2010-10-18 11 views
6

Obecnie wdrażam dwuwymiarową FFT dla rzeczywistych danych wejściowych przy użyciu opencl (dokładniej szybki splot 2D przy użyciu FFT, więc potrzebuję tylko czegoś, co zachowuje się na tyle, aby zastosować splot). 2D FFT jest zaimplementowane za pomocą 1D FFT w wierszach, a następnie 1D FFT na cols.Wydajny 2D FFT na rzeczywistych danych wejściowych?

Aby było to bardziej wydajne, próbuję użyć symetrii FFT z rzeczywistym sygnałem wejściowym, aby móc obliczyć mniejsze FFT. Odkryłem, że mogę łączyć dwa wiersze w jeden, używając pierwszego jako rzeczywistego komponentu, a drugi jako komponent urojonego, zrobić pierwszy 1D FFT w wynikowym wierszu, a następnie użyć właściwości symetrii do skonstruowania wyników 1D FFT poszczególnych wiersze z tego. To, co robię jest zasadniczo następujące:

Niech wiersze z macierzy będą f i g.

  1. Construct x = f + i * g
  2. Transform dostać F(x) = F(f) + i * F(g)
  3. Stosować symetrie wyodrębnić F(f) i F(g) od F(x)

nie mogę jednak wystarczy wpisać wyniki bezpośrednio do 2. 1D FFT, ponieważ w takim przypadku nie przetransformowałbym całej matrycy, ale zamiast tego dwie podmodele. Jednak wyodrębnienie danych między transformacjami oznacza albo zapisanie większej ilości danych (n/2+1 wpisów potrzebnych do wyrażenia wyniku 1D FFT na rzeczywistym wprowadzeniu), albo połączenie elementów o indeksie 0 i indeksu n/2 w jeden element (połączenie z użyciem tej samej sztuczki, ponieważ zarówno liczby są gwarantowane) i używają tej samej ilości pamięci, ale muszą zrobić przypadek podobny do tego w moim splotu.

Ponieważ staram się ponownie używać buforów tak dużo jak to możliwe (z powodu ograniczonej ilości pamięci RAM dostępnej w gpu) użycie większej ilości pamięci nie jest dobrym rozwiązaniem. Ponadto moje algorytmy nie są przystosowane do pracy z matrycami, które nie są potęgą 2/wielokrotności 16 (różni się od jądra do jądra). Wolałbym też unikać specjalnych przypadków, ponieważ sprawiłoby to, że moje jądra byłyby bardziej skomplikowane, co zaszkodziłoby efektywności (mam już problemy z minimalizowaniem liczby rejestrów używanych przez poszczególne jądra).

Moje pytanie brzmi: czy istnieje eleganckie podejście do tego problemu, co oznacza, że ​​będzie działać bez użycia większej ilości pamięci lub specjalnych przypadków dla niektórych elementów?

Idealnie chciałbym móc wykonać całą FFT bez dzielenia połączonych danych w środku FFT, ale nie jestem pewien, czy to możliwe.

+3

Czy będzie to dostępne w miękkiej oprawie w najbliższym czasie? –

+0

Czy naprawdę potrzebujesz skomplikowanego FFT? Prawdopodobnie nie. – phkahler

+0

Dobre pytanie, miałem prawie taki sam problem podczas wykonywania fft do wykrywania steganografii. ale nie zdawałem sobie wtedy sprawy ... że istnieje stackoverflow;/ – dfens

Odpowiedz

2

Hmmm ... moje dwie referencje są:

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

myślę, że zobowiązując się do "danych" hermitowskiego struktura, z wartościami 0 i n/2 umieszczonymi w pierwszym elemencie, jest drogą do wykonania, ponieważ struktury forward/inverse i hermitian będą działać lepiej.

W ten sposób masz rUnWrap (FFT (n/2, parzysty (x) + i * Odd (x))) = rFFT (x), a riFFT może pracować na tablicy "hermitian", tworząc para macierzy parzystych i nieparzystych, która ponownie daje oryginalną strukturę.

Istnieją również inne próbki, które można zrobić, przy czym pierwotna tablica jest podzielona na 4 n/2xn/2 tablic, zakorzenione w (0,0), (0,1), (1,0) , (1,1), a następnie zawinięty na końcu, używając ostatecznego radix-4 pass ... może to jest lepsze dla pamięci GPU ... Nie wiem.

alan

Powiązane problemy