Suche…


Einführung

In diesem Thema werden verschiedene Möglichkeiten beschrieben, wie Daten an einem Ort abgelegt werden können, an dem Ihr Gerät darauf zugreifen kann.

Ein Array lesen

Um ein Array vom Gerät zurück zum Host zu lesen, ruft man an

clEnqueueReadBuffer($queue, $memobj, $blocking, $offset, $size, $target, 0, null, null);

Die $ queue ist die CommandQueue, mit der der Speicher auf dem Gerät zugewiesen wurde. Das $ memobj enthält die Adresse des Gerätespeichers. $ Offset und $ size bestimmen weiter, wo und wie viele Daten kopiert werden. Das $ -Ziel ist ein Zeiger auf den Hostspeicher, in dem die Daten gespeichert werden. Das $ -Ziel muss zugewiesen werden und eine entsprechende Größe haben.

Eine Textur lesen

Das Lesen eines Bildes ist fast wie das Lesen eines Arrays. Der einzige Unterschied besteht darin, dass die Größe und der Versatz dreidimensional sein müssen.

clEnqueueReadImage($queue, $memobj, $blocking, $offset, $size, $stride, $slice_pitch, $target, 0, null, null);

Der $ Schritt definiert, wie viele Bytes eine Zeile hat. Normalerweise ist dies nur width * (Byte pro Pixel), aber jemand möchte dies ändern, um die Daten mit den Speicherbänken abzugleichen. Dasselbe gilt für $ slice_pitch, nur dass dieser Wert für die dritte Dimension gilt.

Eine 2D-Textur schreiben

Um eine Textur auf das Gerät zu kopieren, sind zwei Schritte erforderlich

  1. Weisen Sie den Speicher auf dem Gerät zu
  2. Kopieren Sie das Bild auf das Gerät
  _mem = clCreateImage2D($context, $mem_flags, $image_format, $width, $height, $stride, $source, &err);

Die $ mem_flags definieren, wie der Speicher zugewiesen wird. Es kann entweder nur lesen, nur schreiben oder beides sein. Zusätzlich können Sie festlegen, wo und wie der Speicher zugewiesen wird. $ width, $ height und $ stride sind ziemlich selbsterklärend.

Wenn Ihre mem_flags die Daten kopieren, sind Sie fertig. Wenn Sie dies später manuell tun möchten, müssen Sie eine andere Funktion aufrufen, wenn Sie bereit sind.

err = clEnqueueWriteImage($queue, _mem, $blocking, $offset, $size, $stride, $slice_pitch, $source, 0, null, null);

$ Offset und $ size definieren den Bildbereich, den Sie in den Zielspeicher kopieren möchten. Der $ Schritt definiert, wie viele Bytes eine Zeile hat. Normalerweise ist dies nur width * (Byte pro Pixel), aber jemand möchte dies ändern, um die Daten mit den Speicherbänken abzugleichen. Dasselbe gilt für $ slice_pitch, nur dass dieser Wert für die dritte Dimension gilt. Sowohl $ stride als auch $ slice_pitch müssen mit Ihren Eingabedaten übereinstimmen.

Speicherflags

Bei der Speicherzuweisung haben Sie die Möglichkeit, zwischen verschiedenen Modi zu wählen:

  • Nur-Lese-Speicher
  • Schreibe nur Speicher
  • Lese- / Schreibspeicher

Nur-Lese-Speicher wird in der konstanten Speicherregion zugewiesen, während die anderen beiden in der normalen globalen Region zugewiesen werden.

Zusätzlich zur Erreichbarkeit können Sie festlegen, wo Ihr Speicher zugewiesen wird.

  • Nicht angegeben: Ihr Speicher wird wie erwartet im Gerätespeicher zugewiesen. Der $ source pointer kann auf null gesetzt werden.
  • CL_MEM_USE_HOST_PTR: Dies teilt dem Gerät mit, dass sich die Daten im System-RAM befinden und nicht verschoben werden sollen. Stattdessen werden die Daten direkt im RAM bearbeitet.
  • CL_MEM_COPY_HOST_PTR: Weist das Gerät an, alle Werte unter der angegebenen Adresse in den Gerätespeicher zu kopieren oder mithilfe von CL_MEM_ALLOC_HOST_PTR in einen separaten Speicherbereich im Systemspeicher zu kopieren.
  • CL_MEM_ALLOC_HOST_PTR: Weist das Gerät an, Speicherplatz im Systemspeicher zuzuweisen. Wenn der $ source pointer als einziger Parameter verwendet wird, kann er auf null gesetzt werden.

Schnell ist der Zugriff auf den globalen Gerätespeicher. Sie müssen es jedoch auch zweimal aufrufen, um Daten zu kopieren. Die Verwendung des Hostzeigers ist der langsamste, während Alloc_host_ptr eine höhere Geschwindigkeit bietet.

Bei Verwendung von use_host_ptr macht das Gerät genau das: Es verwendet Ihre Daten im System-RAM, die natürlich vom Betriebssystem aus aufgerufen werden. Daher muss jeder Speicheraufruf die CPU durchlaufen, um mögliche Seitenfehler zu behandeln. Wenn die Daten verfügbar sind, kopiert die CPU diese in den gepinnten Speicher und gibt sie mit wertvollen CPU-Taktzyklen an den DMA-Controller weiter. Im Gegenteil, allocost_host_ptr reserviert im System-RAM einen fixierten Speicher. Dieser Speicher befindet sich außerhalb des Pageswap-Mechanismus und hat daher eine garantierte Verfügbarkeit. Daher kann das Gerät beim Zugriff auf den Systemspeicher die CPU vollständig überspringen und DMA verwenden, um Daten schnell auf das Gerät zu kopieren.

Ein Array schreiben

Das Schreiben eines Arrays besteht aus zwei Schritten:

  1. Speicher zuweisen
  2. Daten kopieren

Um den Speicher zuzuordnen, genügt ein einfacher Anruf

_mem = clCreateBuffer($queue, $mem_flags, $size, $host_ptr, &err);

ist genug. Wenn Sie sich entschieden haben, den Hostzeiger über die mem_flags zu kopieren, sind Sie fertig. Ansonsten können Sie die Daten jederzeit mit kopieren

err = clEnqueueWriteBuffer($queue, _mem, $blocking, $offset, $size, $source, 0, null, null);


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow