截至2013年末,CUDA与OpenCL


34

从程序员的角度来看,CUDA和OpenCL在2013年末之间如何比较?我的小组正在考虑尝试利用GPU计算。通过选择仅支持OpenCL但不支持CUDA的硬件,我们是否会大大限制自己?

具体来说,以下假设是否正确?

  • CUDA中所有可能的功能在OpenCL中也可能

  • 只要我们不使用库,给定的任务就不会很容易(或更难)地完成

  • CUDA的主要优势是库的可用性

  • 两者都对所有三个主要平台(Win / OSX / Linux)都具有良好的支持。


1
如果此问题不够具体,我将尝试更新该问题……我们是该领域的新手,这是出现的基本问题之一,尤其是由于硬件的选择。这个线程引起了我的注意,并使我对OpenCL持谨慎态度。如果OpenCL对于光线追踪(Blender)不够好,那么对于HPC可能也不够...
Szabolcs 2013年

自2011年以来,我就一直没有参与GPU的开发,因此我会让别人提供最新的答案,但是您发现“给定任务在这两个任务中都做起来并不容易,这显然不是一件容易的事”完全正确。这里有个人偏见,但我认为CUDA在开发方便性方面领先于OpenCL。我必须自我更新,但是如果您两年前问我,我会说我不会用10英尺长的杆触碰OpenCL。
奥勒留斯

我知道这个问题:OpenCL的未来,但这不是一个完全相同的问题,而且已有2年历史了。我认为两年后情况可能会有所变化。
Szabolcs

我们面临的一个实际问题是,带有AMD FirePro卡的2013 Mac Pro是否适合于熟悉和利用GPU计算(不支持CUDA)。
Szabolcs

最好还是将C ++ AMP放在雷达上。一个llvm实现正在开发中。hsafoundation.com/bringing-camp-beyond-windows-via-clang-llvm。Microsoft已经为FFT,BLAS和LAPACK创建了C ++ AMP库。
罗杰·达尔

Answers:


37

我将尝试总结在开发ViennaCL的过程中获得的经验,在这些过程中,我们拥有CUDA和OpenCL后端,其中大部分都是许多计算内核的1:1翻译。根据您的问题,我还将假设我们在这里主要使用GPU。

性能可移植性。首先,就您一次编写一个内核而言,它没有性能可移植的内核之类的东西,它可以在每种硬件上高效运行。由于支持的硬件范围更广,因此在OpenCL中更明显,但在CUDA中却没有。在CUDA中,由于所支持的硬件范围较小,因此不太明显,但是即使在这里,我们也必须区分至少三种硬件体系结构(Fermi之前的版本,Fermi和Kepler)。这些性能波动很容易导致20%的性能变化,这取决于您如何协调线程和选择的工作组大小,即使内核像缓冲区副本一样简单。值得一提的是,在Fermi之前的GPU和Fermi的GPU上,可以直接在CUDA中直接编写快速矩阵乘法内核,对于最新的Kepler GPU,似乎必须使用PTX伪汇编语言才能接近CUBLAS的性能。因此,即使是由供应商控制的语言,例如CUDA,似乎也存在与硬件开发保持同步的问题。此外,当您运行nvcc时,所有CUDA代码都会被静态编译,这在某种程度上需要通过-arch标志进行平衡,而OpenCL内核是在运行时从即时编译器进行编译的,因此您原则上可以定制内核具体到特定计算设备的细节。但是,后者相当复杂,通常仅在代码成熟和经验积累时才成为非常有吸引力的选择。要付出的代价是即时编译所需的O(1)时间,在某些情况下这可能是个问题。OpenCL 2。

调试和分析。CUDA调试和性能分析工具最适合GPGPU。AMD的工具也不错,但它们不包括cuda-gdb或cuda-memcheck之类的工具。此外,NVIDIA仍然为GPGPU提供了最强大的驱动程序和SDK,由于漏洞多多的内核而导致的系统冻结实际上是OpenCL和CUDA的例外,而不是常规。由于某些原因,在这里我可能不需要解释,NVIDIA不再为带有CUDA 5.0及更高版本的OpenCL提供调试和配置文件。

可达性和便利性。启动和运行第一个CUDA代码要容易得多,特别是因为CUDA代码与主机代码很好地集成在一起。(我将讨论以后要支付的价格。)网上有很多教程以及优化指南和一些库。使用OpenCL,您必须经过大量的初始化代码并以字符串形式编写内核,因此,在将源提供给jit编译器时,您只会在执行过程中发现编译错误。因此,使用OpenCL进行一个代码/编译/调试周期需要更长的时间,因此在此初始开发阶段,您的生产率通常较低。

软件库方面。尽管先前的项目都支持CUDA,但对于OpenCL来说,与其他软件的集成是一大优势。您可以通过仅链接共享的OpenCL库来使用OpenCL,就是这样,而使用CUDA时,则需要具有整个CUDA工具链。更糟糕的是,您需要使用正确的主机编译器才能使nvcc正常工作。如果您曾经尝试在GCC 4.6或更高版本中使用CUDA 4.2,那么您将很难工作。通常,如果您碰巧使用了比CUDA SDK更新的任何编译器,则可能会出现问题。集成到诸如CMake的构建系统中是另一个令人头痛的原因(您也可以在例如PETSc上找到足够的证据邮件列表)。在您拥有完全控制权的您自己的计算机上,这可能不是问题,但是一旦您分发代码,就会遇到用户在其软件堆栈中受到某些限制的情况。换句话说,使用CUDA,您不再有选择自己喜欢的主机编译器的权限,而是由NVIDIA规定允许使用哪些编译器。

其他方面。CUDA与硬件(例如,翘曲)有点接近,但是我对线性代数的经验是,您很少会从中受益。CUDA还有更多的软件库,但是越来越多的库使用多个计算后端。同时ViennaCLVexCLParalution都支持OpenCL和CUDA后端,其他领域的图书馆也可以看到类似的趋势。

GPGPU不是银弹。事实证明,GPGPU可为结构化操作和计算受限的任务提供良好的性能。但是,对于顺序处理所占份额不可忽略的算法,GPGPU无法神奇地克服阿姆达尔定律。在这种情况下,最好使用可用的最佳算法的良好CPU实现,而不是尝试抛出并行但不太合适的算法来解决问题。另外,PCI-Express是一个严重的瓶颈,因此您需要预先检查GPU的节省是否可以补偿来回移动数据的开销。

我的建议。请考虑使用CUDA OpenCL而不是CUDA OpenCL的。无需不必要地将自己限制在一个平台上,而可以从两全其美中受益。对我而言,最有效的方法是在CUDA中设置初始实现,对其进行调试,对其进行概要分析,然后通过简单的字符串替换将其移植到OpenCL。(您甚至可以参数化OpenCL内核字符串生成例程,以便具有一定的灵活性。通常需要花费不到10%的时间,但是您也可以在其他硬件上运行。您可能会对非NVIDIA硬件在某些情况下的性能表现感到惊讶。最重要的是,应考虑最大程度地重用库中的功能。快速而 对某些功能进行肮脏的重新实现通常可以在CPU上的单线程执行中接受,但在大规模并行硬件上的性能通常很差。理想情况下,您甚至可以将所有内容卸载到库中,而不必担心它们在内部使用CUDA,OpenCL还是同时使用这两者。就我个人而言,从现在开始几年后,我永远都不敢为我想依赖的东西编写供应商锁定的代码,但是这个思想方面应该单独讨论。


您如何看待两个平台中标准1D,2D,3D FFT的当前性能和可用性?
2013年

关于JIT编译,CUDA也提供了这种可能性,但是有一些限制。
BenC

@hwlau:FFT是供应商库的标准功能,因此完全独立于CUDA与OpenCL。
卡尔·鲁普

@BenC:约束确实非常严格,它只是预编译的CUDA内核对底层硬件的专门化。
卡尔·鲁普

1
对此潜在问题有何评论?我不清楚这是AMD硬件还是OpenCL本身存在问题(即NVIDIA上的OpenCL是否不存在问题)。对于大多数科学计算应用程序来说,也许这不是问题,因为它们往往比高级射线追踪器更小,更不复杂?顺便说一句,谢谢您的出色回答!
Szabolcs
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.