2012-09-05 17 views
5

Si se pasa una variable al kernel con CL_MEM_USE_HOST_PTR, ¿significa que también se mostrará algún cambio en la variable del dispositivo en la memoria del host?OpenCL: coherencia de memoria del dispositivo/host para variables pasadas al kernel con CL_MEM_USE_HOST_PTR

Estoy en un escenario en el que estoy usando CPU como dispositivo en lugar de GPU, por lo que todo lo que pasó al núcleo se marcará con CL_MEM_USE_HOST_PTR.

Si esto es cierto, entonces ya no necesito volver a leer todo en el host, lo cual es muy conveniente.

Respuesta

8

Su interpretación es correcta, excepto una posible trampa: documentation establece que

implementaciones OpenCL se les permite almacenar en caché el contenido del búfer apuntado por host_ptr en la memoria del dispositivo. Esta copia en caché se puede usar cuando los kernels se ejecutan en un dispositivo.

Esto significa que los cambios en los datos realizados por kernel podrían no reflejarse inmediatamente en host_ptr. De hecho, no hay garantía de que host_ptr contenga datos válidos mientras se usa para el búfer.

Para tener datos válidos y actualizados, debe forzar la sincronización. La documentación ofcial es un poco vago acerca de este momento, pero buffer mapping/unmapping funciona definitivamente:

Si se crea el objeto buffer con CL_MEM_USE_HOST_PTR set en mem_flags, la host_ptr especificado en clCreateBuffer se garantiza que contienen los últimos bits de la región que se mapea cuando se completó el comando clEnqueueMapBuffer; y el valor del puntero devuelto por clEnqueueMapBuffer se derivará del host_ptr especificado cuando se crea el objeto del búfer.

Aquí es un ejemplo adaptado de Khronos group forum post:

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); 
+2

Este es un sutil Gotcha y he sido mordido por esto también, así que es bueno que trajo esto. – Ani

+0

@aland Creo que estoy preguntando muy tarde ... Pero en lugar de mapear la memoria, si estoy esperando usar el evento ... ¿actualizará mi matriz adecuada en el dispositivo host? para mí está funcionando (podría estar usando evento para dejar que el núcleo termine). pero entonces ¿puedo omitir el mapeo? –

+1

@Vishwadeep Solo esperando a que kernel finalice la ejecución es [* no * suficiente] (http://www.khronos.org/message_boards/showthread.php/6912-Clarify-CL_MEM_USE_HOST_PTR?p=22099&viewfull=1#post22099). Su enfoque podría funcionar, especialmente si está bien, solo usa la CPU como dispositivo de cómputo, pero ese es aún un comportamiento indefinido. – aland

Cuestiones relacionadas