在实验室中,我们有一个异构群集设置,包括许多Intel CPU,一些AMD CPU和几个Nvidia GPU。
对于HPC开发,我知道我可以编写一次并在此设置上随处运行的一件事是OpenCL(甚至不是Java;))。但是在实验室里,我们非常习惯使用C或Fortran + MPI开发完全在CPU上运行,也许很少有人可能需要使用Nvidia的节点在CUDA中运行。
现在,在一个新项目的开始,我认为能够在MPI + OpenCL中编写代码并且能够在分布式处理GPU和CPU中运行相同的OpenCL代码是非常好的。那么,是否可取,OpenCL实现是否已准备好执行此类任务?在使用英特尔SDK的CPU上运行OpenCL代码时,我能算得上与使用英特尔编译器编译的多线程C程序一样好的性能吗?你能指出比较和基准吗?
答案 0 :(得分:2)
OpenCL是可移植的,但它不具备性能可移植性。你不应该期望OpenCL能够在任何地方一次写入快速写入。为GPU编写的OpenCL代码可能在CPU上运行不佳,我不希望GPU之间的性能统一,特别是来自不同供应商的GPU。
为了回答您的具体问题,基于众多第三方评估,不,我不希望OpenCL在Intel CPU上击败编写良好的C + OpenMP。这有很多原因。
请注意,由于问题的广泛性,我的答案中的错误栏非常大。了解您打算计算的内容会更有帮助。
答案 1 :(得分:1)
除了其他答案,并再次强调一个重要观点:问题非常广泛,表现将取决于您在问题中未提及的许多因素。您可能已经意识到这些因素,但有疑问,可以在this answer中找到摘要(乍一看这个问题似乎无关,并且引用了CUDA,但许多概念也适用于OpenCL)< / p>
OpenCL 背后的主要驱动思路之一是 heterogeneous computing(显然,该页面甚至没有提及OpenCL ......)。也就是说,OpenCL旨在为开发人员提供利用所有可用处理资源的可能性,从单个ARM内核到具有数千个内核的多个高端GPU。
这种多功能性需要付出代价。某些概念是为多核架构隐式定制的(或者至少,这似乎是迄今为止的主要应用领域)。在任何情况下,“优化”OpenCL程序通常只是意味着“调整它以便在一个特定架构上运行得特别快”。像矢量化或共享内存这样的东西在一个平台上可能是有利的,或者在另一个平台上根本不可用。
有一些可能绕过这一点,或者至少试图让一个OpenCL程序更加“不可知”它将运行的硬件。一个显而易见的选择是查询目标平台属性(例如,首选矢量大小或共享内存是否可用),并根据结果启动不同的内核。由于OpenCL中内置的编译器,甚至可以将特定于平台的优化(例如,通过#define
)包含到内核源代码中。但是,对于这种优化的努力 - 性能 - 增益比率,很难做出一般性陈述。而且当核心数量增加且OpenCL编译器变得更好时,更难以预测“通用”OpenCL实现的可能性能降低(与完全调整的C实现相比)是否会迟早得到补偿。
所以我的建议是做一些“代表性”任务的基准测试,看看性能是否在不同设备之间具有竞争力,同时要记住每个设备的平均核心数(并且,最有可能是一般的设备的异质性会增加,而OpenCL可能会更容易适应这些变化。
答案 2 :(得分:0)
我很幸运能够在CPU和GPU上移植我的OpenCL代码。我的项目是Levenberg-Marquardt,我首先用C语言编写它来调试它,然后将它移植到Intel CPU上的OpenCL以检查结果并进行更多调试,然后在AMD GPU上进行OpenCL。
我发现在设备上真正编写好OpenCL代码的最佳技巧是将全局内存缓冲到本地内存,即使您使用的是CPU,因为这通常是GPU上的瓶颈。我在GPU与CPU上发现的第二个瓶颈是内核大小,CPU可以处理比GPU更大的内核,因此请记住用于常量的内存类型,分配的本地内存量等等。
已经有大约6个月了,所以可能它已经修复了,但AMD FFT在Intel CPU,GPU和AMD GPU上运行良好,但在NVIDIA GPU上没有用。 AMD论坛有一个主题,它归因于NVIDIA不支持某些矢量功能。