/ / Prozess-Strings aus dem OpenCL-Kernel - c, windows, opencl, gpgpu, nvidia

Verarbeite Strings vom OpenCL-Kernel - c, windows, opencl, gpgpu, nvidia

Es gibt mehrere Zeichenketten wie

std :: string first, second, dritter; ...

Mein Plan war, ihre Adressen in einem char * -Array zu sammeln:

char *addresses = {&first[0], &second[0], &third[0]} ...

und übergeben Sie die char ** -Adressen an den OpenCL-Kernel.

Es gibt mehrere Probleme oder Fragen:

Das Hauptproblem ist, dass ich kein Array von Zeigern übergeben kann.

Gibt es eine gute Möglichkeit, viele Strings aus dem Kernel-Code zu verwenden, ohne sie zu kopieren, sondern im Shared Memory belassen?

Ich verwende NVIDIA unter Windows. Daher kann ich nur die OpenCL 1.2-Version verwenden.

Ich kann die Zeichenfolge nicht verketten, da diese eine andere Struktur haben ...

BEARBEITEN:

Laut der ersten Antwort, wenn ich folgendes habe (Beispiel):

char *p;

cl_mem cmHostString = clCreateBuffer(myDev.getcxGPUContext(), CL_MEM_ALLOC_HOST_PTR, BUFFER_SIZE, NULL, &oclErr);

oclErr = clEnqueueWriteBuffer(myDev.getCqCommandQueue(), cmHostString, CL_TRUE, 0, BUFFER_SIZE, p, 0, NULL, NULL);

Muss ich jedes Element meines Char-Arrays kopieren? vom Hostspeicher zum anderen Teil des Hosts Speicher (und die neue Adresse wird vom Host ausgeblendet)? Das ist mir nicht logisch. Warum kann ich nicht dieselbe Adresse verwenden? Ich könnte direkt vom GPU-Gerät auf den Arbeitsspeicher des Hosts zugreifen und ihn verwenden.

Antworten:

0 für die Antwort № 1

Gibt es eine gute Möglichkeit, viele Strings aus dem Kernel-Code zu verwenden, ohne sie zu kopieren, sondern im Shared Memory belassen?

Nicht in OpenCL1.2. Das Shared Virtual Memory-Konzept ist seit OpenCL 2.0 verfügbar, das von NVidia noch nicht unterstützt wird. Sie müssen entweder auf eine GPU umschalten, die OpenCL 2.0 unterstützt, oder für OpenCL 1.2 müssen Sie Ihre Zeichenfolgen in ein fortlaufendes Array von Zeichen kopieren und an (Kopieren) übergeben der Kernel


BEARBEITEN: Auf Ihre Bearbeitung antworten - Sie können Folgendes verwenden:

  • CL_MEM_ALLOC_HOST_PTR kennzeichnen, um einen leeren Puffer der erforderlichen Größe zu erstellen, und ordnen Sie diesen Puffer dann mit zu clEnqueueMapBuffer und füllen Sie es mit dem Zeiger, der vom Mapping zurückgegeben wird. Danach den Puffer mit Hilfe von clEnqueueUnmapMemObject.
  • CL_MEM_USE_HOST_PTR kennzeichnen, um einen Puffer der erforderlichen Größe zu erstellen, und übergeben Sie dort den Zeiger auf Ihr Array von Zeichen

Aus meiner Erfahrung erstellter Puffer mit CL_MEM_USE_HOST_PTR flag ist normalerweise etwas schneller, ich denke obDaten werden wirklich kopiert oder nicht unter der Haube hängt von der Implementierung ab. Um dies zu verwenden, müssen Sie jedoch zunächst Ihr Array von Zeichen auf dem Host vorbereiten.

Grundsätzlich müssen Sie Benchmarking durchführen und sehen, was istschneller. Konzentrieren Sie sich auch nicht zu sehr auf das Kopieren von Daten. Dies sind in der Regel kleine Zahlen (Übertragungen in GB / Sek.) Im Vergleich dazu, wie lange es dauert, den Kernel auszuführen (hängt natürlich davon ab, was im Kernel ist).