当我开始在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);
这显然要求我以块的形式对数据进行分区,确保每个块都适合设备内存。执行计算后,我用clEnqueueReadBuffer()读出数据。但是,在某些时候我意识到我可以使用以下行:
cl_mem buff = clCreateBuffer(cl_ctx, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, object_size, (void*) object, NULL);
执行此操作时,数据的分区已过时。令我惊讶的是,我的表现得到了极大的提升。这是我不明白的事情。从我得到的,当使用主机指针时,设备内存作为缓存工作,但所有数据仍然需要复制到它进行处理,然后一旦完成就复制回主内存。为什么使用显式副本(clEnqueRead / WriteBuffer)慢一个数量级,在我看来它应该基本相同?我错过了什么吗?
感谢。
答案 0 :(得分:2)
是的,您在clEnqueueWriteBuffer调用中缺少CL_TRUE。这使得写操作阻塞,这使得在复制时使CPU停止。使用主机指针,OpenCL实现可以通过使副本异步来“优化”副本,因此整体而言性能更好。
请注意,这取决于CL实现,并且无法保证更快/更慢/更慢。
答案 1 :(得分:1)
在某些情况下,CPU和GPU可以共享相同的物理DRAM内存。例如,如果内存块满足CPU和GPU对齐规则,则Intel会将CL_MEM_USE_HOST_PTR解释为在CPU和GPU之间共享物理DRAM的权限,因此不会实际复制数据。显然,这非常快!
这是一个解释它的链接:
PS我知道我的回复对OP来说太老了,但其他读者可能会感兴趣。