我一直在使用openCL作为执行运行时C代码的通用方法。虽然我有兴趣让代码最终在GPU上运行,但我目前正在研究CPU上的OpenCL开销与运行直接编译的C相比。
显然,在OpenCL中预制和编译内核会产生开销。但即使我只是在最后执行和缓冲区读取时间:
clEnqueueNDRangeKernel(...);
clFinish();
clEnqueueReadBuffer(...);
与直接C代码(因子30)相比,简单计算的开销很大,即使有1000个循环,也给它一个并行化的机会。显然,从OpenCL代码读取缓冲区会产生开销......但它位于同一个CPU上,因此不会产生大量开销。
这听起来不错吗?
答案 0 :(得分:1)
对clEnqueueReadBuffer()
的调用最有可能执行类似memcpy
的操作,这种操作成本高且非最佳。
如果您想避免这种情况,您应该正常在主机上分配数据(例如,使用malloc()
或new
)并将CL_MEM_USE_HOST_PTR
标记传递给clCreateBuffer()
时您创建OpenCL缓冲区对象。然后使用clEnqueueMapBuffer()
和clEnqueueUnmapMemObject()
将数据传入/传出OpenCL,而不实际执行副本。这应该接近最佳w.r.t.最小化OpenCL开销。
对于实现此技术的更高级抽象,请查看mapped_view<T>
中的Boost.Compute类(简单示例here)。