2 Stimmen

CUDA: Methode zur Partitionierung *großer* Probleme?

Dieser ganze CUDA-Quatsch ist in seiner Leistungsfähigkeit überwältigend, aber etwas, über das ich mich wundere, ist die harte Begrenzung der 1d-Block-/Gitterabmessungen (normalerweise 512 bzw. 65535).

Gibt es bei Problemen, die in ihrem Umfang viel größer sind (in der Größenordnung von Milliarden), eine automatisierte programmatische Möglichkeit, eine "Warteschlange" durch einen Kernel zu bilden, oder ist es ein Fall von manuellem Schneiden und Würfeln?

Wie geht man mit der Problemaufteilung um?

1voto

talonmies Punkte 69030

Wenn eindimensionale Gitter zu klein sind, verwenden Sie stattdessen zweidimensionale (oder dreidimensionale auf Fermi mit CUDA 4.0) Gitter. Die Dimensionalität in Raster- und Blocklayouts dient eigentlich nur der Bequemlichkeit - sie lässt den Ausführungsraum wie die üblichen parallelen Dateneingabebereiche aussehen, mit denen Programmierer zu arbeiten gewohnt sind (Matrizen, Raster, Voxel usw.). Aber es ist nur eine sehr kleine Abstraktion vom zugrundeliegenden einfachen linearen Nummerierungsschema, das über 10^12 eindeutige Thread-IDs innerhalb eines einzigen Kernel-Starts handhaben kann.

Bei Gittern ist die Reihenfolge spaltenbezogen. Wenn Sie also zuvor ein 1D-Gitterproblem hatten, wurde der "eindeutige 1D-Fadenindex" wie folgt berechnet:

unsigned int tid = threadIdx.x + blockIdx.x * blockDim.x;

was eine theoretische Obergrenze von 512 * 65535 = 33553920 einzelnen Threads hat. Das entsprechende 2D-Gitterproblem ist nur eine einfache Erweiterung des 1D-Falls

size_t tidx = threadIdx.x + blockIdx.x * blockDim.x;
size_t tid = tidx + blockIdx.y * blockDim.x * GridDim.x;

das eine theoretische Obergrenze von 512 * 65535 * 65535 = 2198956147200 einzelnen Threads hat. Fermi erlaubt es, dem Gitter eine dritte Dimension hinzuzufügen, ebenfalls mit einer maximalen Größe von 65535, was bis zu etwa 10^17 Threads in einem einzigen Ausführungsgitter ergibt. Das ist ziemlich viel.

1voto

Ashwin Nanjappa Punkte 72122

Es gibt 2 grundlegende Möglichkeiten, Ihre Daten zu partitionieren, damit Sie sie mit CUDA bearbeiten können:

  1. Aufteilung der Daten in zusammenhängende Brocken , so dass jeder Thread an einem Chunk arbeitet.
  2. Jeder Thread knabbert an einem Datenelement. Wenn alle Threads fertig sind, verschieben sie sich um numberOfThreads und wiederholen den Vorgang.

Ich habe diese Techniken anhand einfacher Beispiele erläutert aquí . Methode 2 ist in der Regel einfacher zu kodieren und für die meisten Aufgaben zu verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X