OpenCL如何分发工作项?

时间:2018-06-06 13:42:09

标签: performance concurrency opencl gpu nvidia

我正在测试和比较GPU加速与不同数量的工作项(没有工作组)。我正在使用的内核是一个非常简单但很长的操作。当我使用多个工作项进行测试时,我使用屏障功能并将工作拆分为较小的块,以获得与仅使用一个工作项相同的结果。我使用cl_event测量内核执行时间,结果如下:

  • 1个工作项目:35735毫秒
  • 2个工作项:11822毫秒(比1个工作项快3倍)
  • 10个工作项目:2380毫秒(比2个工作项目快5倍)
  • 100个工作项目:239毫秒(比10个工作项目快10倍)
  • 200个工作项目:122毫秒(比100个工作项目快2倍)

CPU平均需要大约580 ms来执行相同的操作。

我不理解也无法解释的唯一结果是有2个工作项的结果。我希望速度比只有一个工作项的速度提高约2倍,那为什么它是3?

我试图通过研究这些工作项如何在处理元素上分布来理解这些数字。我假设如果我只有一个内核,则只激活一个计算单元(或多处理器),并且工作项分布在该计算单元的所有处理元件(或CUDA核心)上。我还不确定的是,处理元素是否可以同时处理多个工作项,还是每个处理元素只是一个工作项?

CL_DEVICE_MAX_WORK_ITEM_SIZES是1024/1024/64和CL_DEVICE_MAX_WORK_GROUP_SIZE 1024.由于我只使用一个维度,这是否意味着每个处理元素或每个计算单元可以同时运行1024个工作项?当我尝试使用1000个工作项时,结果是一个较小的数字,所以我认为并非所有这些都被执行了,但为什么会这样呢?

我的GPU信息:Nvidia GeForce GT 525M,96个CUDA核心(2个计算单元,每个单元48个CUDA核心)

1 个答案:

答案 0 :(得分:2)

  

我唯一不理解也无法解释的结果是2的结果   工作项目。我希望速度提高约2倍   与只有一个工作项的结果相比,为什么它是3?

确切的原因可能很难确定,但这里有一些建议:

  • 对于少量工作项,未对所有进行优化。对标准结束进行基准测试并不是特别有用。
  • 对于GPU来说,35秒是很长的时间。您的GPU可能还有其他事情要做,因此您的工作项可能会被多次中断,每次都会保存并恢复上下文。
  • 这在很大程度上取决于你的算法。例如,如果您的内核使用本地内存或工作大小相关的私有内存量,它可能会“溢出”到全局内存,这将减慢速度。
  • 根据内核的内存访问模式,您可能会遇到读/写合并的影响。更多的工作项意味着更少的内存访问。
  

我还不确定处理元素是否可以同时处理多个工作项,还是每个处理元素只是一个工作项?

大多数GPU硬件都支持某种形式的SMT来隐藏内存访问延迟。因此,计算核心一次最多会有一些固定数量的工作项,如果其中一个被阻塞等待内存访问或屏障,则核心将继续在另一个工作项上执行命令。请注意,如果内核使用大量本地内存或专用寄存器,则可以进一步限制最大并发线程数,因为这些是计算单元中所有内核共享的有限资源。

工作组通常一次只能在一个计算单元上运行,因为本地内存和屏障不能跨单元工作。所以你不想让你的团队太大。

最后一点:计算硬件往往按2的幂分组,因此通常最好将工作组大小设置为例如2的倍数。 16或64. 1000都不是,这通常意味着一些核心什么都不做。

  

当我尝试使用1000个工作项时,结果是一个较小的数字,所以我认为并非所有这些都被执行了,但为什么会这样?

请在这个问题上更精确,不清楚你在问什么。