Aufwandsschätzung in Sachen Cuda-Parallelisierung



  • Ich habe noch nie mit GPGPU gearbeitet, und würde euch da gerne fragen, wie aufwendig es wäre, eine einfache Farbraumtransformation in Cuda umzusetzen.

    Es handelt sich um die YUV->RGB Transformation aus dem JPEG2000 Standard. Im Prinzip passiert da nichts großartiges außer ein paar Subtraktionen und Bitshifts. Allerdings sind in der momentanten Implementierung einige doubles vorhanden... ich hörte Grafikkarten mögen Sachen, die größer sind als floats, nicht?

    Dabei werden einfach in einem Eingangsarray jedes Element nach der Reihe abgearbeitet. Ist also denke ich vollkommen parallelisierbar, ohne Haken.

    Hört sich das sehr trivial an oder sollte ich mich da auf mehr Einlesezeit + Implementierungszeit vorbereiten, als es sich anhört?



  • Hört sich sehr einfach an. Nur was genau erhofft ihr euch davon? Wenn ihr nicht gerade sehr große Bilder habt, würd ich mal vermuten dass das ganze hin und her kopieren der Daten zwischen CPU und GPU sich nicht grad auszahlt, wenn ihr nicht mehr damit tut. Ich würd erstmal versuchen, die CPU Implementierung zu optimieren. Du sagst ihr mischt double mit float? Das ist z.B. schonmal etwas, was ihr nicht tun solltet, wenn ihr Performance wollt. Wofür braucht ihr in dieser YUV nach RGB Transformation doubles!? Bedenkt auch, dass CUDA nur auf NVIDIA Grafikkarten läuft...



  • Ich hab mir den Algorithmus noch nicht angeschaut (ich hab praktisch nur den Code den ich Copy&Paste wo ich ihn brauche und hatte bis jetzt noch keine Lust, den Algorithmus nachzvollziehen. War ne lahme Woche :P), daher weiss ich nicht warum da doubles verwendet werden. Das spezielle an dem spezifischen Algorithmus ist, dass er theoretisch und praktisch verlustfrei transformiert, wobei die meisten anderen Verfahren hier und da wohl mal ein Bit verlieren. Vielleicht hat es etwas damit zu tun.

    Was das hin und herkopieren angeht: Das sollte nicht so tragisch sein, oder? Der momentate Brute-Force, single-core Algorithmus braucht ~80ms für die Transformation über 1920x1080x3 16Bit-Datenfelder. Ich denke nicht, dass ich das ohne großen Zeitaufwand (um den geht es ja hier: Maximale Performance pro Implementierungszeit rausholen) auf unter 10 ms drücken könnte.

    Diese 10ms sollte doch eine Cuda-Implementierung schlagen können, oder?



  • Ach ja, wenn das mit Cuda nicht zu schwer wäre, gäbe es da noch eine Wavelet-Transformation davor, die mit umgebaut werden könnte 🙂



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Rund um die Programmierung verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • der aufwand mit cuda ist sehr klein, installiere das Cuda5 toolkit SDK. gleich bei der installation wirst du am ende gefragt, ob du das vectorAdd sample starten willst. das kannst du dann sehr einfach modifizieren um statt nur "Add" dann die ganze konvertierung zu machen. sollte vielleicht 1h arbeit sein das hinzubekommen.

    wobei:

    eine YUV zu RGB konvertierung (vom JPG layout) braucht 18flops, was bei 1920x1080 in 37.32MFlops und ca 6MB resultiert.
    zur GPU koennt ihr mit ca 5GB/s rechnen -> 6(MB)/5120(MB/s) -> 11ms transferzeit pro richtung -> ca 22ms wird es dauern.
    Sagen wir du hast einen typischen 3GHz prozessor und nutzt nur die FPU, dann solltest du 3GFlops/s an double rechenleistung haben, das bedeutet 37.32(gf)/3000(gf/s) -> 12.44ms. (wobei ich hier der einfachheithalber untertreibe, eigentlich sollten FPUs 2 oder 3 verarbeitungsports auslasten koennen -> 4ms bis 6ms)

    wie dot vermutet (allerdings nicht bildgroessen abhaengig) wird es sich nicht sonderlich auszahlen diese konvertierung auf der GPU zu machen. mit cuda koennt ihr die daten zwar als main-memory allokation anlegen und wenn cpu+mobo+gpu gut zusammenarbeiten, voll duplex lesen/schreibend direkt auf dem hauptspeicher arbeiten, aber ich wuerde nicht erwarten dass ihr unter die 12ms kommt.
    auf der anderen seiten, mit SSE habt ihr gute chancen die verarbeitung doppelt so schnell zu bekommen, bis ihr schlicht an der speicher bandbreite saturiert.



  • Schon mal die Intel IPP angeschaut. Damit solltet ihr es mal probieren. Da gibt es auch was fuer Wavelets etc.



  • ich glaube ipp hat das ganze jpeg2000 codec. (h264,jpg,mpeg,mp3... alles drinnen).



  • rapso schrieb:

    ich glaube ipp hat das ganze jpeg2000 codec. (h264,jpg,mpeg,mp3... alles drinnen).

    Ich hab den Standard heute mal an der passenden Stelle überflogen, und ohne Context des Textes vor dieser Stelle hörte es sich danach an, als biete JPEG2000 Auswahl zwischen einem Verlustfreien, dafür etwas langsameren und einem nicht-Verlustfreien (genauer gesagt sprechen die da von "reversible" und "irreversible", was aber am Ende wohl nur heißen kann, dass es auf decode-Seite zu kleinen Verlusten kommt) Algorithmus.

    IPP implementiert leider nur den Verlustbehafteten Algorithmus. Der Verlustfreie arbeitet übrigens ausschließlich mit Integer-Operationen. Ich weiss jetzt nicht ob ich den hier einfach so posten darf ... naja im Prinzip sind es 2 Subtraktionen, 2 Additionen, 3 Zuweisungen und ein Bitshift (alles +- 1 Operation, bin mir gerade nicht so sicher). Außenrum ist dann noch ein wenig Zeug um min/max-Values nicht zu über/unterschreiten, aber das sollte es gewesen sein wenn ich's richtig in Erinnerung habe.

    Achja, das double-Gedoens konnte man problemlos ausbauen.

    Übrigens danke für die kurze Runterrechnung. 11 ms für Datentransfer ist schon sehr übel. Nur für Wavelet-Transformation und YUV->RGB wird sich das wohl aber nicht lohnen (die sind beide relativ trivial Vektorisierbar). Ich werde morgen einfach mal eine SSE2 Version implementieren und schauen wie weit ich damit komme.



  • IPP implementiert leider nur den Verlustbehafteten Algorithmus. Der Verlustfreie arbeitet übrigens ausschließlich mit Integer-Operationen. Ich weiss jetzt nicht ob ich den hier einfach so posten darf ... naja im Prinzip sind es 2 Subtraktionen, 2 Additionen, 3 Zuweisungen und ein Bitshift (alles +- 1 Operation, bin mir gerade nicht so sicher). Außenrum ist dann noch ein wenig Zeug um min/max-Values nicht zu über/unterschreiten, aber das sollte es gewesen sein wenn ich's richtig in Erinnerung habe.

    Die IPP hat auch die ganzen Trivialoperationen wie Addition, Subtraktione, Farbtransformationen, ... Du wirst niemals schneller sein als die IPP. Hinzu kommt der Mehraufwand einer eigenen Implementation, du must selbst auf das Alignment achten und mit SSE2 reizt du wohl modernere Prozessoren nicht Aus.

    Kenne mich mit JPEG nicht aus, aber die IPP hat Functions for Lossless JPEG Coding.



  • knivil schrieb:

    IPP implementiert leider nur den Verlustbehafteten Algorithmus. Der Verlustfreie arbeitet übrigens ausschließlich mit Integer-Operationen. Ich weiss jetzt nicht ob ich den hier einfach so posten darf ... naja im Prinzip sind es 2 Subtraktionen, 2 Additionen, 3 Zuweisungen und ein Bitshift (alles +- 1 Operation, bin mir gerade nicht so sicher). Außenrum ist dann noch ein wenig Zeug um min/max-Values nicht zu über/unterschreiten, aber das sollte es gewesen sein wenn ich's richtig in Erinnerung habe.

    Die IPP hat auch die ganzen Trivialoperationen wie Addition, Subtraktione, Farbtransformationen, ... Du wirst niemals schneller sein als die IPP. Hinzu kommt der Mehraufwand einer eigenen Implementation, du must selbst auf das Alignment achten und mit SSE2 reizt du wohl modernere Prozessoren nicht Aus.

    Kenne mich mit JPEG nicht aus, aber die IPP hat Functions for Lossless JPEG Coding.

    Hab ich schon gesehen, aber da ist nichts dabei was ich brauche 🙂 (ich programmiere hier ja auch keinen JPEG2000 coder/decoder, sondern verwende nur die Farbtransformation aus dem Standard).

    Zu den Standardoperationen: Aja? Ich hab gerade nochmal nachgeschaut, und es sieht aus als würden Funktionen wie ipp_add irgendwas tatsächlich auf rohen Arrays operieren. Da sie in "Image Processing" und nicht in nem Kapitel wie "Standard Operations" waren, bin ich wohl einfach davon ausgegangen, dass diese Funktionen irgendwelche Annahmen über den Inhalt der Daten machen, was aber anscheinend nicht so ist. Danke!


Anmelden zum Antworten