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