OpenCL 在 GTX Titan 上比 CUDA 慢两倍

OpenCL twice as slow as CUDA on GTX Titan

我有一个刚刚在 ArrayFire 中实现的光束传播算法。我在我的 GTX Titan 卡上使用 OpenCL 后端。使用 OpenCL,它是 运行,每分钟大约 25,000 步。然后我将它切换到 CUDA 后端,性能上升到每分钟大约 50,000 步。这有点令人惊讶,但我认为它可能使用了 OpenCL 中不可用的一些更高级的功能。然后我 运行 使用我的 GTX 960 卡进行相同的测试。它 运行 使用 OpenCL 时每分钟大约 22,000 步,使用 CUDA 时每分钟大约 23,000 步。这很令人困惑,因为我预计它会遵循与 Titan 相同的模式。此外,我认为我在使用 GT 730M 的笔记本电脑上看到了 2 倍的性能变化。我听说 nvidia 在某些显卡上会降低 OpenCL 的速度。他们对 700 系列这样做吗?

既然你没有给出任何代码,我只能提供一个分析器。例如,我使用的是 amd 的 codexl,所有图片均来自过度同步的卷积算法,该算法使用 768x768 矩阵上的 50x50 画笔区域计算。有很多整数和局部整数数组和整数运算,最后有同样多的 fp 运算,会导致一些问题(工作在 3 个设备上平衡)。

我相信 nvidia 有类似的软件来检测您的应用程序中的漏洞。

  • CPU 每个函数的时间分析让您了解主机端的热点。此处列出了前 5 个最耗时的函数。因此,您可以优化主机功能。(单击其中一个功能会显示每个内核 cpu 条指令的详细性能计数器)

  • 内核分析显示向量单元是否存在任何瓶颈, 标量单位、内存操作和更多选项。这里可以看到内核占用和波前数,但右侧还有数十个其他东西。

当你点击kerneoccupancy cell时,你可以看到详细的瓶颈来源,如下图:

  • 应用程序时间线跟踪分析揭示了 ndRangeKernel、读写操作、clFinish 和其他 API 方法之间的差距,因此您可以查看是否存在冗余同步、多线程操作瓶颈和内存泄漏。(下图在垂直和水平方向上都显示了漏洞,因为此示例没有每个设备的异步操作并且存在冗余同步)

  • 此外,gtx 960 无法击败 titan,除非工作负载对 960 来说足够大,对 titan 来说足够小(可能只是 api 不同设备处理造成的开销)。它可能是每个单元有 192 个内核的 titan(每组 384 - 768 个线程更好)和每个单元有 128 个内核的 gtx960(每个组有 256 - 512 -1024 个线程更好的并行性)
  • 每分钟 25000 次迭代是每秒 416 次,即每步大约 2.5 毫秒。 2.5 毫秒意味着您在此时间片只能传输 10-40 MB。发送的缓冲区大小是多少?过多的 clFinish 函数导致至少数百微秒,当内核时间相当时(如 1-2 毫秒)

  • 增加执行规模,使 titan 的负载足以实现最佳性能(而非峰值)。

  • 当工作负载太小时,我的 R7-240(320 核)优于我的 HD7870(1280 核),因为 r7 的内核占用率更高,因为每个计算单元有更多的波前,ALU 是fed %100(占用),也有更少的计算单元来准备计算(开销)和更少的硬件同步(开销)。这就是为什么有不同类别的基准,例如 "performance" 和 "extreme"。较新的架构也更接近其峰值性能。

  • 可能,gtx 960 可能无法同时管理 3 个 array-fire 应用程序 运行(@ 15000/m),而 titan 可能同时管理 8-10 个应用程序(例如 @ 15000/m)(如果您选择应用程序级并行性而不是简单地增加每步的工作量)。

编辑:示例代码实际上是在计算类似扩散的交互。圆形源周围区域的平衡态material:

所有颜色通道的色带来自将 fp 舍入到 0-255 整数范围(rgba-每个 1 字节,应该使用浮点数但没有足够的 pci-e 预算)