考虑以下代码,该代码从大小为double的数组中创建缓冲区内存对象:
coef_mem = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, (sizeof(double) * size), arr, &err);
考虑将它作为内核的arg传递。根据运行内核的设备,有两种可能:
以下是我对两种可能性的问题:
答案 0 :(得分:6)
从主机传输到设备的内存是什么步骤?
唯一的保证是,在内核开始执行时,数据将在设备上。 OpenCL规范故意不强制要求何时发生这些数据传输,以便允许不同的OpenCL实现做出适合其自身硬件的决策。如果您在上下文中只有一个设备,则在创建缓冲区后立即执行传输 。根据我的经验,这些传输通常在内核入队时(或不久之后)发生,因为当实现知道真正需要特定设备上的缓冲区时。但这完全取决于实施。
如何衡量将内存从主机传输到设备所需的时间?
使用分析器,通常会显示这些传输何时发生以及需要多长时间。如果您使用clEnqueueWriteBuffer
传输数据,则可以使用OpenCL事件概要分析系统。
如何衡量将内存从设备的全局内存传输到专用内存所需的时间?
再次使用分析器。大多数分析器在从全局存储器读取时具有获得的带宽的度量,或类似的东西。但它实际上并不是从全局到私有内存的明确转移。
如果设备与主机设备相同,是否仍会传输内存?
使用CL_MEM_COPY_HOST_PTR
,是的。如果您不希望转移发生,请改用CL_MEM_USE_HOST_PTR
。使用统一内存架构(例如集成GPU),典型的建议是使用CL_MEM_ALLOC_HOST_PTR
在主机可访问内存中分配设备缓冲区(通常是固定的),并使用clEnqueueMapBuffer
访问它。
从主机转移到设备所需的时间是否大于从设备的全局内存转移到专用内存所需的时间?
可能,但这取决于架构,是否有统一的内存系统,以及如何实际访问内核中的数据(内存访问模式和缓存会产生很大影响)。