2016-04-18 20 views
1

Ich muss einen RLE in CUDA dekodieren und ich habe versucht, über die effizienteste Möglichkeit der Erweiterung des RLE in eine Liste mit all meinen Werten nachzudenken. Also sag meine Werte sind 2, 3, 4 und meine Läufe sind 3, 3, 1 Ich möchte das auf 2, 2, 2, 3, 3, 3, 4 erweitern.RLE effizient dekodieren in CUDA

Zuerst dachte ich, ich könnte verwenden cudaMemset aber ich bin mir ziemlich sicher, dass jetzt ein Kernel startet und ich CUDA Compute Capability 3.0 habe. Selbst wenn es wahrscheinlich nicht ineffizient wäre, einen neuen Kernel für jedes Paar aus Value/Run zu starten, steht dafür kein dynamischer Parallelismus zur Verfügung.

Also ich möchte wissen, ob diese Lösung solide ist, bevor ich gehe und es implementieren, da es so viele Dinge gibt, die nicht gut auf CUDA funktionieren, wenn Sie nicht klug sind. Wäre es sinnvoll, einen Kernel zu erstellen, der cudaMalloc dann cudaMemCpy an das Ziel ruft? Ich kann leicht die Präfix-Summen berechnen, um zu wissen, wo ich den Speicher hin- und herkopieren soll und damit alle meine Lesevorgänge zusammengeführt werden. Worüber ich mir Sorgen mache, ist cudaMalloc und cudaMemCpy so oft anzurufen.

Eine weitere mögliche Option besteht darin, diese Werte in den gemeinsamen Speicher zu schreiben und diese dann in den globalen Speicher zu kopieren. Ich möchte wissen, ob meine erste Lösung funktionieren und effizient sein soll oder ob ich die zweite Lösung machen muss.

Antwort

3

Sie möchten nicht über eine separate Operation nachdenken (z. B. cudaMalloc oder cudaMemset) für jedes Wert/Laufpaar.

Nach dem Berechnen der Präfixsumme in der Ausführungsreihenfolge ist der letzte Wert in der Präfixsumme die gesamte Zuweisungsgröße. Verwenden Sie das für eine einzelne cudaMalloc Operation für die gesamte endgültige erweiterte Sequenz.

Sobald Sie den erforderlichen Speicherplatz zugewiesen und die Präfix Summe berechnet haben, ist die tatsächliche Erweiterung ziemlich einfach.

thrust kann dies ziemlich einfach machen, wenn Sie einen schnellen Prototyp wollen. Es gibt an example code dafür.

+0

Robert Sie sind einer der tollsten Menschen um. Du hast jedes Problem gelöst, auf das ich jemals in CUDA gestoßen bin. Vielen Dank! – flips

0

@RobertCrovella ist natürlich korrekt, aber Sie können noch weiter in Sachen Effizienz gehen, wenn Sie den Spielraum haben, Ihre Kompressionsstimmung etwas zu zwicken.

Entschuldigung für das Self-Plugging, aber Sie könnten interessiert sein an my own implementation einer Variante der Lauflängencodierung, mit der zusätzlichen Verankerung der Ausgangspositionen in den Eingang (z. B. "in welchem ​​Offset in welchem ​​Lauf wir tun Hast du das 2048. Element? "); Dies ermöglicht eine gerechtere Zuordnung von Arbeit zu Thread-Blöcken und vermeidet die Notwendigkeit einer vollständigen Präfix-Summe. Es ist immer noch ein Work-in-Progress, so dass ich zum Zeitpunkt des Schreibens nur ca. 34 GB/sec auf einer 336 GB/sec Speicherbandbreitenkarte (Titan X) bekomme, aber es ist ziemlich brauchbar.