CUDA和OpenCL性能比较

21

我正在使用CUDA 6.0和随CUDA SDK捆绑的OpenCL实现。我为每个平台都有两个相同的内核(它们在平台特定关键字方面不同)。 它们仅读取和写入全局内存,每个线程位于不同的位置。 CUDA的启动配置是200块250线程(1D),这直接对应于OpenCL的配置-50,000全局工作大小和250本地工作大小

OpenCL代码运行得更快。这可能吗?还是我的计时方式有误?我了解到,NVIDIA的OpenCL实现基于CUDA的OpenCL实现。我用OpenCL获得了约15%的性能提升。

如果您能够说明我可能会看到的原因以及NVIDIA实现CUDA和OpenCL之间的一些差异,那将是很好的。


1
OpenCL和CUDA是完全不同的。它们最终都使用相同的硬件,但就像OpenGL和DirectX一样,一个不在另一个之下或反之亦然。主要的观点是库不同、编译器不同,执行模型也不同。有些部分可能是共同的,但大多数不是。 - DarkZeros
2
如果您使用的是64位平台,我的第一猜测是OpenCL内核受益于较低的寄存器压力,因为它可以是32位的。如果OpenCL工具链允许,您应该反编译这两个内核并比较微代码。 - ArchaeaSoftware
3
NVIDIA的OpenCL实现是32位的,不符合CUDA相同的函数调用要求。CUDA运行时应用程序将内核代码编译为与应用程序相同的位数。在64位平台上,尝试将CUDA应用程序编译为32位应用程序。您对double的使用与应用程序或内核代码的位数无关。可以从OpenCL内核获取PTX代码,以便与CUDA代码进行比较。目前无法获取OpenCL内核的SASS代码。 - Greg Smith
2
使用OpenCL和CUDA得到的数字答案是否相同?如果不相同,则内核没有执行相同的计算。 - Tim Child
3
我知道这个问题已经有一年了,我可能在指出显而易见的问题,但是如果您正在使用CUDA运行时API,请注意CUDA在运行内核代码之前必须初始化驱动程序,这可能会与OpenCL相比扭曲您的计时。尝试在进行计时之前运行一些虚拟迭代的内核代码。 - jcxz
显示剩余10条评论
1个回答

27
现代GPU上执行的内核几乎从未是计算受限的,而几乎总是受限于内存带宽。(因为与可用的通向内存的路径相比,运行的计算核心太多了。)这意味着给定内核的性能通常在很大程度上取决于给定算法展示的内存访问模式。
实际上,这使得很难预测(甚至理解)预期的性能。
你观察到的差异可能是由于OpenCL与CUDA工具链使用不同优化导致的两个内核之间的内存访问模式微妙差异所致。
要了解如何优化GPU内核,最好学习可用的内存缓存硬件的详细信息,以及如何最佳地利用它。(例如,在OpenCL中,有选择地使用“本地”内存缓存 versus 总是直接访问“全局”内存。)

3
我的几乎所有GPU核函数都受到计算约束,我不知道你在做什么。 - étale-cohomology
当然,拥有计算密集型内核是非常正常的,但一旦您开始在内核中访问内存(如上所述),物理路径到内存很快就会饱和(由于数千个线程发送内存请求)。这就是为什么GPU制造商如此重视优化内存带宽硬件的原因。 - Shebla Tsama

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接