2010-08-08 15 views
5

Cuando empecé a programar en OpenCL que utiliza el siguiente enfoque para proporcionar datos a mis granos:Memoria en OpenCL

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE, object_size, NULL, NULL); 
clEnqueueWriteBuffer(cl_queue, buff, CL_TRUE, 0, object_size, (void *) object, NULL, NULL, NULL); 

Obviamente, esto requería que particionar mis datos en fragmentos, lo que garantiza que cada trozo encajaría en la memoria del dispositivo. Después de realizar los cálculos, leía los datos con clEnqueueReadBuffer(). Sin embargo, en algún momento me di cuenta de que sólo podía utilizar la siguiente línea:

cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, object_size, (void*) object, NULL); 

Al hacer esto, la partición de los datos se hizo obsoleto. Y para mi sorpresa, experimenté un gran impulso en el rendimiento. Eso es algo que no entiendo. Por lo que obtuve, cuando uso un puntero de host, la memoria del dispositivo funciona como un caché, pero todos los datos aún tienen que copiarse para su procesamiento y luego copiarlos nuevamente a la memoria principal una vez que haya terminado. ¿Cómo es que usar una copia explícita (clEnqueRead/WriteBuffer) es un orden de magnitud más lento, cuando en mi opinión debería ser básicamente el mismo? ¿Me estoy perdiendo de algo?

Gracias.

Respuesta

2

Sí, falta la CL_TRUE en la llamada clEnqueueWriteBuffer. Esto hace que la operación de escritura bloquee, lo que detiene la CPU mientras se realiza la copia. Usando el puntero de host, la implementación de OpenCL puede "optimizar" la copia haciéndola asíncrona, por lo tanto, en general, el rendimiento es mejor.

Tenga en cuenta que esto depende de la implementación de CL, y no hay garantía de que será más rápido/igual/más lento.

+0

Conozco el indicador de bloqueo en clEnqueueRead/WriteBuffer. Sin embargo, cuando hice las medidas, utilicé un clFinish (al menos estoy bastante seguro de que lo hice), que debería tener el mismo efecto que la bandera de bloqueo, ¿o no? Eso es, por supuesto, solo si se procesa la misma cantidad de datos. Hm, tal vez la implementación de CL es lo suficientemente inteligente como para omitir la parte de un objeto al que no se accede (alrededor del 70%) ... ¡Gracias de todos modos! – VHristov

1

En algunos casos, la CPU y la GPU pueden compartir la misma memoria DRAM física. Por ejemplo, si el bloque de memoria cumple las reglas de alineación de CPU y GPU, Intel interpreta CL_MEM_USE_HOST_PTR como permiso para compartir DRAM física entre la CPU y la GPU, por lo que no hay una copia real de los datos. Obviamente, ¡eso es muy rápido!

Aquí hay un enlace que lo explica:

https://software.intel.com/en-us/articles/getting-the-most-from-opencl-12-how-to-increase-performance-by-minimizing-buffer-copies-on-intel-processor-graphics

PS Sé que mi respuesta es demasiado viejo para OP, pero otros lectores pueden estar interesados.