编写多个内核或单个内核

时间:2012-02-29 18:46:41

标签: opencl

假设我有两大功能。在单独的内核中编写它们并按顺序调用它们会更好吗,还是最好只编写一个内核? (我不想回读数据并在主机和设备之间强制形成)。如果我想多次调用内核,速度会怎样?

3 个答案:

答案 0 :(得分:11)

要考虑的一件事是寄存器压力对硬件利用率和性能的影响。

作为一般规则,大内核具有很大的寄存器占用空间。典型的OpenCL设备(即GPU)具有非常有限的寄存器文件大小,并且大内核可以导致较低的并发性(较少的并发warp / wavefronts),较少的延迟隐藏机会和较差的整体性能。另一方面,在大多数平台上,内核启动开销相当低,因此如果您的算法在执行的“阶段”之间没有大量的状态,那么使用多个内核的代价可能会相当低。

使用多个内核还有另一个好处 - 您可以免费获得所有工作单元之间的隐式同步。通常,这可以消除对原子内存操作和同步原语的需要,这可能对代码性能产生负面影响。

最终指南应该是衡量表现。对于这类事情,没有普遍的经验法则。基准测试是唯一可以确定的方法。

答案 1 :(得分:3)

一般来说,这是一个(可能)性能略高于代码可读性的问题。只要将它们保存在同一个上下文中,复制缓冲区就没有问题。例如。你可以将内核的一个输出缓冲区设置为下一个内核的输入缓冲区,这不会涉及任何复制。

答案 2 :(得分:3)

在OpenCL中编写代码的正确方法是将代码分离为并行任务,并且每个任务都是内核。也就是说,每个“for循环”应该是一个内核。有时单个CPU代码函数可能会导致OCL中的4内核实现。

如果需要在内核执行之间存储数据,只需使用OpenCL缓冲区,不要复制到主机(这解决了DEVICE< - > HOST瓶颈)。

如果两个函数对不同的数据起作用,则可以编写单个内核,但这取决于正在运行的操作的复杂性。