Intel Xeon Phi OpenCL优化指南建议使用映射缓冲区在主机和设备内存之间进行数据传输。 OpenCL规范还指出,该技术比必须将数据显式写入设备内存要快。我正在尝试测量来自主机设备和设备主机的数据传输时间。
我的理解是OpenCL框架支持两种传输数据的方式。
以下是我总结的情景:
一个。显式方法:
- Writing: ClWriteBuffer(...)
{ - Invoke execution on device: ClEnqueueNDRangeKernel(kernel) }
- Reading: ClReadBuffer(...)
非常简单。
湾隐含方法:
- Writing: ClCreateBuffer(hostPtr, flag, ...) //Use flag CL_MEM_USE_USE_PTR. make sure to create aligned host buffer to map to.
{ - Invoke execution on device: ClEnqueueNDRangeKernel(kernel) }
- Reading: ClEnqueueMapBuffer(hostPtr, ...) //device relinquishes access to mapped memory back to host for reading processed data
不是很直接。
我正在使用第二种方法。在什么时候开始写入和读取数据传输?我需要在我的代码的正确位置插入时间码,以查看它需要多长时间。到目前为止,我已经在ClEnqueueNDRangeKernel(内核)之前插入了它;在ClEnqueueMapBuffer(hostPtr,...)之前进行阅读。我的时间的数字非常小,我怀疑这些是从主机到设备内存(对于这种隐式方法)的数据传输实际开始的点。
对于对涉及使用这三个API命令的数据传输进行概要分析的任何说明将不胜感激。
谢谢, 戴夫
答案 0 :(得分:1)
你需要使用制造商提供的工具(我认为vtune放大器完成了英特尔硬件上的工作)来查看设备中实际发生的事情,因为OpenCL规范有意允许实现余地何时实际执行。
所以我只能告诉你什么时候允许设备工作以及什么时候被迫这样做。
你打电话后
ClCreateBuffer(hostPtr, flag, ...)
允许设备开始读取数据。它可以在您的程序正常运行时执行此操作,因为在您调用EnqueueMapBuffer之前不允许您在那里写入。您很可能在传输完成之前调用EnqueueNDRangeKernel,因此它只是在命令队列中挂起。
所有这些线和设备只允许工作,没有任何东西迫使它工作,所以在某些情况下它可能还没有真正做过任何事情。但随后出现强制它评估所有内容/等待调用完成的调用,假设您将其设置为阻塞调用。
ClEnqueueMapBuffer(hostPtr, ...)
如果您使用blocking_map作为true运行此调用,那么您实际上将在此时获得现成的数据。该实现使您在该调用内等待,直到数据在设备中,由内核处理然后写回。
如果您不将其作为阻止映射运行,则数据不一定回来。所以你刚刚发出了3个非阻塞调用,设备可以做任何想做的事情。
tl; dr:从写入,执行到读取的所有内容都可以在阻塞clEnqueueMapBuffer调用中发生。