我想了解如何在OpenCL中正确使用async_work_group_copy()调用。我们来看一个简化的例子:
__kernel void test(__global float *x) {
__local xcopy[GROUP_SIZE];
int globalid = get_global_id(0);
int localid = get_local_id(0);
event_t e = async_work_group_copy(xcopy, x+globalid-localid, GROUP_SIZE, 0);
wait_group_events(1, &e);
}
引用http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/async_work_group_copy.html说“执行从src到dst的num_elements gentype元素的异步副本。异步副本由工作组中的所有工作项执行,因此必须遇到此内置函数由执行具有相同参数值的内核的工作组中的所有工作项;否则结果是未定义的。“
但这并不能澄清我的问题......
我想知道,如果以下假设是正确的:
奖金问题:
一个。我可以使用barrier(CLK_LOCAL_MEM_FENCE)而不是wait_group_events()并忽略返回值吗?如果是这样,那会更快吗?
湾本地副本是否也适用于CPU上的处理,或者是否因为共享缓存而产生开销?
此致 斯蒂芬
答案 0 :(得分:12)
这个函数存在的一个主要原因是允许驱动程序/内核编译器有效地复制内存,而开发人员不必对硬件做出假设。
您描述了需要复制的内存,就好像它是单线程副本一样,async_work_group_copy使用并行硬件为您完成。
针对您的具体问题:
我从未见过async_work_group_copy仅被组中的某些工作项使用。我一直认为这是因为它需要它。我认为wait_group_events的阻塞性质会强制所有工作项成为副本的一部分。
是。所有工作项的源(和目标)地址必须相同。
您可以减去本地ID以获取正确的地址,但我发现基于groupId的地址也可以解决此问题。 (get_group_id)
是。最后一个参数是元素的数量,而不是以字节为单位的大小。
一个。不会。基于事件,您会发现工作项几乎立即触及您的屏障,并且不一定会复制数据。这是有道理的,因为一些opencl硬件甚至可能根本不使用计算单元来进行实际的复制操作。
湾我认为cpu opencl实现可能会在您使用本地内存时保证L1缓存的使用。确定这种性能是否更好的唯一方法是使用各种设置对应用程序进行基准测试。