VexCL、Thrust和Boost.Compute之间的区别

43

对于这些库的初步了解,它们看起来非常相似。我知道VexCL和Boost.Compute使用OpenCL作为后端(虽然v1.0版本的VexCL也支持CUDA作为后端),而Thrust使用CUDA。除了不同的后端外,它们有什么区别。

具体来说,它们解决的问题空间是什么,为什么要选择其中之一。

此外,在Thrust FAQ中指出:

OpenCL支持的主要障碍是缺乏支持C++模板的OpenCL编译器和运行时

如果这是真的,那么VexCL和Boost.Compute怎么可能存在呢?


别忘了 C++ AMP! :) - ScarletAmaranth
1个回答

71
我是VexCL的开发者,但我真的很喜欢Boost.Compute作者Kyle LutzBoost邮件列表上对同一主题的看法。简而言之,从用户的角度来看,Thrust、Boost.Compute、AMD的Bolt和可能还有微软的C++ AMP都实现了类似STL的API,而VexCL是一个基于表达式模板的库,更接近Eigen的性质。我认为STL-like库之间的主要区别在于它们的可移植性。
  1. Thrust仅支持NVIDIA GPU,但也可以通过其OpenMP和TBB后端在CPU上运行。
  2. Bolt使用AMD扩展到OpenCL,这些扩展仅适用于AMD GPU。它还提供了Microsoft C++ AMP和Intel TBB后端。
  3. 唯一支持Microsoft C++ AMP的编译器是Microsoft Visual C++(尽管将C++AMP带到Windows之外的工作正在进行中)。
  4. Boost.Compute似乎是其中最便携的解决方案,因为它基于标准的OpenCL。

这些库都试图实现类似于STL的接口,因此具有广泛的适用性。VexCL是专为科学计算而开发的。如果Boost.Compute早些时候开发,我可能可以在其基础上构建VexCL : )。另一个值得关注的科学计算库是ViennaCL,它是一个免费的开源线性代数库,可用于多核架构(GPU、MIC)和多核CPU的计算。请参考[1]了解VexCL、ViennaCL、CMTL4和Thrust在该领域的比较。

关于Thrust开发者无法添加OpenCL后端的引用:Thrust、VexCL和Boost.Compute(我不熟悉其他库的内部)都使用元编程技术来完成它们所做的事情。但由于CUDA支持C++模板,因此Thrust开发人员的工作可能会更加容易:他们必须编写元程序,借助C++编译器生成CUDA程序。 VexCL和Boost.Compute作者编写的元程序生成生成OpenCL源代码的程序。请查看slides,其中我试图解释VexCL的实现方式。因此,我同意当前Thrust的设计禁止他们添加OpenCL后端。

[1] Denis Demidov,Karsten Ahnert,Karl Rupp,Peter Gottschling,使用现代C++库编程CUDA和OpenCL:一个案例研究, SIAM J. Sci. Comput., 35(5), C453–C472. (arXiv版本也可用)。

更新:@gnzlbg评论称,在基于OpenCL的库中没有对C++函数和lambda表达式的支持。确实,OpenCL基于C99并且从存储在字符串中的源代码编译,因此没有简单的方法完全与C++类交互。但是公平地说,基于OpenCL的库确实支持用户定义的函数,甚至在某种程度上也支持lambda表达式。

Boost.Compute提供了自己的简单lambda实现(基于Boost.Proto),并允许通过BOOST_COMPUTE_ADAPT_STRUCTBOOST_COMPUTE_CLOSURE宏与用户定义的结构进行交互。
VexCL提供了类似于线性代数的DSL(也基于Boost.Proto),并且支持将通用的C++算法和函数对象转换(甚至是Boost.Phoenix lambda)为OpenCL函数(有限制)。
我相信AMD的Bolt通过其C++ for OpenCL扩展魔法支持用户定义的函数对象。

话虽如此,基于CUDA的库(也许还有C++ AMP)具有实际的编译时编译器优势(你甚至可以这么说吗?),因此与用户代码的集成可以更加紧密。


您可能想要添加的是,基于OpenCL的库不支持将函数对象(和lambda表达式)作为内核,而那些不基于OpenCL的库通常支持。 - gnzlbg
你对那些库中模拟函数对象支持的特性进行了非常好的总结!干得好!你提到的 AMD Bolt 的 C++ for OpenCL 扩展魔法其实就是 C++AMP。 - gnzlbg
那似乎只是一个模板函数,但在下面一点的地方使用了一个OpenCL字符串内部的模板。这是标准的OpenCL还是AMD特有的?我不知道你可以这样做! - gnzlbg
1
是的,我可能漏掉了一点。这里是扩展规范。这里是一个公告 - ddemidov
如果您能在字符串内部编写“模板”,似乎您也可以为不同类型编写不同的“重载”,只要您有一个 type_name<T>() 函数。这肯定值得在 OpenCL 中这样做(否则其他人不会这样做)。然而,对于我来说,缺乏本地函数对象/lambda等功能是致命的特性,也是选择 C++AMP/CUDA 的原因。希望 C++AMP 很快就会合并到 clang 主干中。 - gnzlbg
显示剩余7条评论

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