我一直在阅读GPU线程是轻量级的,您可以向它们抛出许多任务以并行完成。...但是,它们到底有多轻量级?
比方说,我有一个百万成员的float3数组,我想计算每个float3值的长度。
将一百万个任务发送到GPU是否有意义(因此内核会计算全局数组的单个float3长度并返回)?或者更像1000个任务,每个内核执行循环遍历数组的1000个成员?如果将这样的任务分组有好处,是否有一种方法可以计算每个分组的最佳大小?
答案 0 :(得分:1)
如果仅谈论GPU,答案是-非常轻巧。
将基本上100万个任务发送到GPU是否有意义
您不是要“发送一百万个任务”到GPU。您正在发送一个单个请求,该请求只有几十个字节,实质上是“请使用我在此处给您的网格坐标启动此代码的一百万个副本”。这些“副本”是由GPU内部的硬件动态创建的,是的,它非常有效。
1000个任务,每个内核执行循环遍历数组的1000个成员
在GPU上,您几乎肯定不想这样做。现代高端GPU轻松拥有4000多个处理单元,因此您至少需要 并发量。但是通常更高。有一个调度程序,它选择一个硬件线程在每个处理单元上运行,通常每个处理单元有几十个硬件线程。因此,看到具有100K +硬件线程的GPU并不少见。这是隐藏内存延迟所必需的。
因此,如果您启动具有1000x1网格大小的内核,则很可能会不使用3/4的GPU,用过的部分将花费90%的时间来等待内存。继续尝试。 GPU已经过设计设计,可以处理大量的线程-不要害怕使用它们。
现在,如果您谈论的是CPU,则情况有所不同。 CPU显然没有数千个硬件线程。在这里,它取决于OpenCL的实现-但是我认为,当今最合理的CPU OpenCL的实现将通过在足够多的CPU硬件线程中循环处理工作来为您解决这个问题。
TL; DR:使用“一百万个任务”解决方案,并尝试调整本地工作量。