Gibt es beim Aufrufen eines CUDA-Kernels für eine bestimmte Thread-Konfiguration strenge Regeln? Welche Kernel-Parameter des Speicherbereichs (device / host) sollten sich befinden und welchen Typ sollten sie haben?
Angenommen, ich starte ein 1-D-Gitter von Threads mit
%Vor% Kann ich einen ganzzahligen Parameter int foo
übergeben, der eine Host -integer Variable ist,
direkt zum CUDA-Kernel? Oder sollte ich cudaMalloc
Speicher für eine einzelne ganze Zahl sagen dev_foo
und dann cudaMemcpy
foo
in devfoo
und dann devfoo
als Kernel-Parameter übergeben?
Die Regeln für Kernel-Argumente sind eine logische Konsequenz der C ++ - Parameterübergaberegeln und der Tatsache, dass Gerät und Host-Speicher physisch getrennt sind.
CUDA erlaubt das Übergeben von Argumenten nicht als Referenz und Sie müssen vorsichtig mit Zeigern umgehen.
Insbesondere müssen Sie Parameter nach Wert übergeben. Das Übergeben benutzerdefinierter Typen erfordert, dass der Standardkopiekonstruktor oder Ihr eigener Kopierkonstruktor (falls vorhanden) keine Speicherzuordnungen enthält (Heapzuweisungen mit "new" oder "malloc").
Zusammenfassend eignet sich pass-by-value für integrale, Gleitkomma- oder andere primitive Typen und einfache flache benutzerdefinierte Strukturen oder Klassenobjekte.
Sie müssen nur cudaMalloc()
und cudaMemcpy()
für Datenblöcke verwenden. Nicht einzelne int
s und dergleichen. Sie können auch struct
s als Parameter übergeben, solange keine Mitglieder auf einen Datenblock im Host-Speicher zeigen.
Als Faustregel gilt: Wenn Sie einen Zeiger auf einen Kernel übergeben, stellen Sie sicher, dass er auf den Gerätespeicher zeigt.