Ihr Verständnis korrekt ist, außer einer möglichen Gefahr: documentation besagt, dass
OpenCL-Implementierungen sind erlaubt durch host_ptr
in Gerätespeicher den Pufferinhalt zu spitz zwischenzuspeichern. Diese zwischengespeicherte Kopie kann verwendet werden, wenn Kernel auf einem Gerät ausgeführt werden.
Das bedeutet, dass Änderungen an Daten, die vom Kernel ausgeführt werden, möglicherweise nicht sofort in host_ptr
widergespiegelt werden. In der Tat gibt es keine Garantie, dass host_ptr
gültige Daten enthält, während es für den Puffer verwendet wird.
Um gültige und aktuelle Daten zu haben, müssen Sie die Synchronisation erzwingen. Die offcial Dokumentation ist ein wenig vage zu diesem Moment, aber buffer mapping/unmapping arbeitet definetly:
Wenn der Puffer-Objekt mit CL_MEM_USE_HOST_PTR
Satz in mem_flags
erstellt wird, die host_ptr
in clCreateBuffer
angegeben ist garantiert die neuesten Bits in die enthalten Region wird zugeordnet, wenn der clEnqueueMapBuffer
Befehl abgeschlossen ist; und der Zeigerwert , der von clEnqueueMapBuffer
zurückgegeben wird, wird von der host_ptr
abgeleitet, die angegeben wird, wenn das Pufferobjekt erstellt wird.
Hier ist ein Beispiel von Khronos group forum post angepasst:
cl_mem device_output = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, size, original_output, NULL);
// run the kernel
void* pointer = clEnqueueMapBuffer(queue, device_output, CL_TRUE, CL_MAP_READ, size, 0, 0, NULL, NULL, NULL);
// work with 'original_output'
clEnqueueUnmapMemObject(queue, device_output, pointer, 0, NULL, NULL);
clReleaseMemObject(device_output);
Dies ist eine subtile Gotcha und ich habe auch von diesem gebissen worden, so ist es gut Sie dies gebracht. – Ani
@aland ich denke, ich frage sehr spät .. Aber anstatt den Speicher abzubilden, wenn ich mit Event warten .. wird es meine richtige Array in Host-Gerät aktualisieren? Für mich funktioniert es (vielleicht verwende ich Event, um den Kernel zu beenden). aber kann ich dann das Mapping überspringen? –
@ Vishwadeep Nur warten, bis der Kernel die Ausführung beendet hat, ist [* nicht * genug] (http://www.khronos.org/message_boards/showthread.php/6912-Clarify-CL_MEM_USE_HOST_PTR?p=22099&viewfull=1#post22099). Ihr Ansatz könnte funktionieren, insbesondere wenn Sie nur CPU als Rechengerät verwenden, aber das ist immer noch undefiniert Verhalten. – aland