我有一个刚刚在 ArrayFire 中实现的光束传播算法。我在 GTX Titan 卡上使用了 OpenCL 后端。使用 OpenCL,它以每分钟大约 25,000 步的速度运行。然后我将它切换到 CUDA 后端,性能提高到每分钟大约 50,000 步。这有点令人惊讶,但我认为它可能使用了 OpenCL 中没有的一些更高级的功能。然后我使用我的 GTX 960 卡进行了相同的测试。它使用 OpenCL 以每分钟 22,000 步的速度运行,使用 CUDA 以每分钟 23,000 步的速度运行。这很令人困惑,因为我预计它会遵循与泰坦相同的模式。此外,我认为我在使用 GT 730M 的笔记本电脑上看到了 2 倍的性能变化。我听说 nvidia 在某些卡上减慢了 OpenCL 的速度。他们为 700 系列做这个吗?
1 回答
由于您没有显示任何代码,我只能提供一个分析器。例如,我正在使用 amd 的 codexl,所有图片均来自过度同步的卷积算法,该算法使用 50x50 的画笔区域在 768x768 矩阵上计算。最后有很多整数和本地整数数组和整数运算以及同样多的 fp 运算,会导致一些问题(工作在 3 个设备上平衡)。
我确信 nvidia 有类似的软件来检测您的应用程序中的漏洞。
- 每个函数的 CPU 时间分析让您了解主机端的热点。此处列出的前 5 个最耗时的功能。因此您可以优化主机功能。(单击其中一项功能会显示每个核心的 cpu 指令的详细性能计数器)
- 内核分析通过向量单元、标量单元、内存操作和更多选项显示是否存在任何瓶颈。这里可以看到内核占用率和波前数,但右手边还有很多其他的东西。
当你点击 kerneloccupancy 单元格时,你可以详细地看到瓶颈的来源,如下图所示:
- 应用程序时间线跟踪分析暴露了 ndRangeKernel、读写操作、clFinish 和其他 API 方法之间的间隙,因此您可以查看是否存在冗余同步、多线程操作中的瓶颈和内存泄漏。(下图显示了垂直和水平方向的孔,因为此示例没有每个设备的异步操作,并且有冗余同步)
- 此外,gtx 960 也无法击败泰坦,除非工作量对 960 来说足够大并且对泰坦来说足够小(可能只是不同设备处理导致的 api 开销)。它可能是 Titan 每单元有 192 个内核(每组 384 - 768 个线程更好)和 gtx960 每单元有 128 个内核(每组 256 - 512 -1024 个线程更好的并行性)
每分钟 25000 次迭代是每秒 416 次,即每步大约 2.5 毫秒。2.5 毫秒意味着您在这个时间片上只能传输 10-40 MB。发送的缓冲区大小是多少?过多的 clFinish 函数会导致至少数百微秒,当内核时间相当时(如 1-2 毫秒),这具有可观察到的延迟
增加执行规模,使 Titan 负载足以达到最佳性能(不是峰值)。
当工作负载太小时,我的 R7-240(320 核)优于我的 HD7870(1280 核),因为 r7 中的内核占用率更高,因为每个计算单元有更多的波前,并且 ALU 的馈送率为 %100(占用率),还有更少的计算单元来准备计算(开销)和更少的硬件同步(开销)。这就是为什么有不同类别的基准,例如“性能”和“极限”。此外,较新的架构更接近其峰值性能。
可能,一个 gtx 960 可能无法同时管理 3 个您的阵列触发应用程序(@ 15000/m),而 Titan 可能同时管理 8-10 个应用程序(例如,@ 15000/m)(如果您选择应用程序级别并行性,而不是简单地增加每一步的工作量)。
编辑:示例代码实际上是计算类似扩散的交互。圆形源材料周围的区域平衡状态:
色带来自将 fp 舍入到所有颜色通道的 0-255 整数范围(rgba-每个 1 字节,应该使用浮点数但 pci-e 预算不足)