Forum: PC-Programmierung OpenCL C: diskr. Fourier-Trafo


von Maxim (Gast)


Lesenswert?

Das ist OpenCL C. float2 ist ein Vektor-Datatyp. Ich benutze es zur 
Darstellung imaginärer Zahlen. Z.B. entspricht z = 2 + 3i: float2 z = 
(float2)(2.0, 3.0);
1
#define PI      3.141592653589
2
3
float2 mulc(float2 a, float2 b)
4
{
5
    return (float2)(a.s0 * b.s0 - a.s1 * b.s1, a.s0 * b.s1 + a.s1 * b.s0);
6
}
7
8
__kernel void dft(__global float * input,
9
                  __global float * outputRe,
10
                  __global float * outputIm,
11
                  __global int * N)
12
{
13
    int n, p = get_global_id(0);
14
    float2 sum = (float2)(0.0, 0.0);
15
    
16
    for(n = 0; n < N[0]; n++)
17
    {
18
        sum += mulc((float2)(input[n], 0.0),
19
                    (float2)(cos(2 * PI * n * p / N[0]),
20
                            -sin(2 * PI * n * p / N[0])));
21
    }    
22
    
23
    outputRe[p] = sum.s0;
24
    outputIm[p] = sum.s1;
25
}

Die Ergebnisse stimmen nicht. Eine Gaußglocke wird in ein ganz anderes 
Gebilde transformiert. Sieht jemand den Fehler auf Anhieb?

von Maxim (Gast)


Lesenswert?

PS: Das Eingangssignal ist rein reell, deshalb gibt es nur input statt 
inputRe und inputIm ...

von dumdidum (Gast)


Lesenswert?

Hallo,

habe mehr mit Cuda gearbeitet, Dein Code sieht jedoch so erstmal richtig 
aus. Ich vermute es gibt ein Problem bei entweder :

a) Der Ansteuerung der Kernel (Daten nicht richtig hoch/runter kopiert, 
Speicheranforderung...)
b) Dem Test des Codes. Ist die Gauss-Glocke 'mittig' um die Null? 
Ansonsten solltest Du nur im absolut-betrag eine Gauss-Glocke erhalten. 
Zum Testen bietet sich eher ein cosinus an.

von Maxim (Gast)


Lesenswert?

Vielen Dank! Ich habe das Ergebnis falsch interpretiert, der Fehler lag 
also bei mir. :)

Eine Frage zum Thema: Es gibt ja fertige FFT-Bibliotheken sowohl von AMD 
als auch von Nvidia für OpenCL. Sind diese signifikant schneller als 
eine eigene FFT-Implementierung in OpenCL? Bzw. lässt sich deren 
Geschwindigkeit rel. einfach erreichen?

von dumdidum (Gast)


Lesenswert?

keine Ursache! Ich kenne nur die FFT-Bibliothek von Cuda, und ich finde 
sie ist überraschend langsam. (ungefähr x8 schneller als Matlab und das 
bei einer GTX 580). D.h. ohne es ausprobiert zu haben :

- Es ist wahrscheinlich möglich schneller zu werden.
- Es ist leider vermutlich nicht so einfach

von Maxim (Gast)


Lesenswert?

Nun habe ich eine Woche investiert und gerade einmal die 1D-FFT 
hinbekommen. Auf einer Dualcore-CPU läuft diese ca. fünfmal langsamer 
als die FFT-Routine von numpy (python). D.h. es fällt einiges an 
Overhead für OpenCL an. Jedoch sollte dieser Nachteil mit einer GPU dann 
nicht mehr so sehr ins Gewicht fallen. Ich habe auch extra die 
Implementation ohne Bitreversing genommen, da hierbei die Caches besser 
genutzt werden (weniger verstreute Zugriffe). Die Hälfte der Arbeit 
(wenn nicht mehr) geht alleine darauf, die Arrayindizes für die Ein- und 
Ausgabe zu berechnen. Schade ...

von Matthias N. (nippey)


Lesenswert?

Hey,

habe in den letzten 3 Tagen den Radix-2-Algorithmus von Cooley and Tukey 
nach OpenCL portiert.
Sowohl das erste mal mit OpenCL/GL als auch FFTs gearbeitet.

Eine Abfolge aus 2D-FFT, Gauss-Filterung, 2D-iFFT, Drawing via OpenGL 
für ein 256x256-Bild läuft auf einem Intel i7 Dualcore ~3,3GHz mit 
36FPS.
(Ohne Daten-Transfer, immer das selbe Bild!)
Ich freue mich schon auf eine vernünftige GPU für meinen Arbeitsrechner! 
;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.