2010-12-07 8 views
2

Ich entwickle eine kleine Anwendung mit CUDA.
Ich habe eine riesige 2d-Array (wird nicht auf Shared Memory passen), in denen Threads in allen Blöcken von ständig an zufälligen Orten gelesen werden.
Dieses 2d-Array ist ein schreibgeschütztes Array.
Wo sollte ich dieses 2d-Array zuweisen? globaler Speicher? Konstanter Speicher? Texturspeicher?Cuda Verschiedene Speicherzuordnungen

+0

Ich bin mir sicher, dass Sie wissen, aber zufällige Lesevorgänge sind nicht der beste Ort für eine Anwendung CUDA. Texturen sind für räumliche Lokalität optimiert, aber wenn Sie Lesevorgänge zufällig sind, gibt es keine räumliche Lokalität. Basierend auf diesem würde ich mit globalen gehen ... Aber Sie können keine Geschwindigkeitszunahme über CPU-Implementierungen basierend auf dem Zugriffsmuster sehen. – Marm0t

Antwort

2

Je nach Größe des Texturspeichers Ihres Geräts sollten Sie es in diesem Bereich implementieren. In der Tat basiert der Texturspeicher auf dem sequentiellen Lokalisierungscachemechanismus. Dies bedeutet, dass Speicherzugriffe optimiert werden, wenn Threads aufeinanderfolgender Identifikatoren versuchen, Datenelemente innerhalb relativ enger Speicherpositionen zu erreichen.
Außerdem ist diese Lokalität hier für 2D-Zugriffe implementiert. Wenn also jeder Thread ein Datenelement eines im Texturspeicher gespeicherten Arrays erreicht, sind Sie im Fall von aufeinanderfolgenden 2D-Zugriffen. Folglich nutzen Sie die Speicherarchitektur voll aus.

Leider ist dieser Speicher nicht so groß und mit riesigen Arrays könnten Sie Ihre Daten in die Datenbank einfügen. In diesem Fall können Sie nicht vermeiden, den globalen Speicher zu verwenden.

+0

Die Frage ist spezifisch ... "zufällige Orte". Das sind keine guten Nachrichten für den Cache !! – jmilloy

+0

Richtig, aber wir können es durchaus für sinnvoll halten, Daten im Texturspeicher zu platzieren, da es nur auf Cache-Fehltreffer das Äquivalent eines Lesens aus dem Gerätespeicher kostet! Selbst mit wahlfreiem Zugriff erreichen Sie also sicher zwischengespeicherte Elemente und profitieren vom Textur-Cache. – jopasserat

0

Wenn es klein genug ist, um es konstant oder Textur zu passen, würde ich nur alle drei versuchen.

Eine interessante Option, die Sie hier nicht aufgelistet haben, ist gemappter Speicher auf dem Host. Sie können auf dem Host, auf den vom Gerät aus zugegriffen werden kann, Speicher zuweisen, ohne ihn explizit in den Gerätespeicher zu übertragen. Abhängig von der Größe des Arrays, auf das Sie zugreifen müssen, könnte es schneller sein als das Kopieren in den globalen Speicher und das Lesen von dort.

1

Ich stimme dem jHackTheRipper, eine einfache Lösung wäre, Textur Speicher und dann Profil mit dem Compute Visual Profiler zu verwenden. Heres a good set of slides from NVIDIA über die verschiedenen Speichertypen für Bildkonvolution; Es zeigt, dass eine gute gemeinsame Speicherbelegung und globale Lesevorgänge nicht zu viel schneller waren als die Verwendung von Texturspeicher. In Ihrem Fall sollten Sie einige zusammengefasste Lesevorgänge aus dem Texmemory erhalten, die Sie normalerweise beim Zugriff auf zufällige Werte im globalen Speicher nicht erhalten würden.

+0

Schöne Dias! Noch einmal, abhängig von der verwendeten Architektur: z.B. Nicht zusammengewachsene Zugriffe haben einen geringeren Einfluss auf die Speicherleistung auf Geräten der Compute Capability 2.0 (Fermi). – jopasserat

+0

Guter Punkt, aber das Schreiben von gut optimiertem Code für Compute 1.0 führt zu großartigen 2.0-Beschleunigungen – Ljdawson