英特尔的线程构建模块 (TBB)开源库看起来非常有趣。即使有一本关于这个主题的O'Reilly 书,我也没有听说有很多人在使用它。我有兴趣将它用于 Unix(Mac、Linux 等)环境中的一些多级并行应用程序(MPI + 线程)。对于它的价值,我对高性能计算/数值方法类应用感兴趣。
有没有人有 TBB 的经验?它运作良好吗?它是否相当可移植(包括 GCC 和其他编译器)?该范式是否适用于您编写的程序?还有其他我应该研究的图书馆吗?
英特尔的线程构建模块 (TBB)开源库看起来非常有趣。即使有一本关于这个主题的O'Reilly 书,我也没有听说有很多人在使用它。我有兴趣将它用于 Unix(Mac、Linux 等)环境中的一些多级并行应用程序(MPI + 线程)。对于它的价值,我对高性能计算/数值方法类应用感兴趣。
有没有人有 TBB 的经验?它运作良好吗?它是否相当可移植(包括 GCC 和其他编译器)?该范式是否适用于您编写的程序?还有其他我应该研究的图书馆吗?
我已经将它引入到我们的代码库中,因为当我们迁移到 16 核机器时,我们需要一个 bettor malloc 来使用。对于 8 岁及以下,这不是一个重大问题。它对我们来说效果很好。我们计划接下来使用细粒度的并发容器。理想情况下,我们可以利用产品的真正内涵,但这需要重新考虑我们如何构建代码。我真的很喜欢 TBB 中的想法,但是在代码库上进行改造并不容易。
您不能将 TBB 视为另一个线程库。他们有一个全新的模型,它真正位于线程之上并将线程抽象出来。你学会思考任务、parallel_for 类型的操作和管道。如果我要构建一个新项目,我可能会尝试以这种方式对其进行建模。
我们在 Visual Studio 中工作,它工作得很好。它最初是为 linux/pthreads 编写的,所以在那里运行也很好。
我不做数值计算,但我从事数据挖掘(想想聚类和分类),我们的工作负载可能相似:所有数据都是静态的,你在程序开始时就有了。我简要调查了英特尔的 TBB,发现它们对我的需求来说太过分了。在开始使用基于 pthread 的原始代码后,我切换到 OPENMP 并在可读性和性能之间获得了正确的组合。
TBB 是便携式的。它支持 Intel 和 AMD(即 x86)处理器、IBM PowerPC 和 POWER 处理器、ARM 处理器以及可能的其他处理器。如果查看构建目录,您可以看到构建系统支持的所有配置,包括各种操作系统(Linux、Windows、Android、MacOS、iOS、FreeBSD、AIX 等)和编译器(GCC、英特尔、Clang/LLVM、IBM XL 等)。我没有使用 PGI C++ 编译器尝试过 TBB,并且知道它不适用于 Cray C++ 编译器(截至 2017 年)。
几年前,我参与了将 TBB 移植到 IBM Blue Gene 系统的工作。静态链接是一个挑战,但现在由big_iron.inc构建系统帮助程序解决。其他问题是支持相对古老的 GCC 版本(4.1 和 4.4)并确保 PowerPC atomics 正常工作。我希望在提供或兼容 GCC 和 POSIX 的平台上移植到任何当前不受支持的体系结构都相对简单。
我知道至少有两个使用 TBB 的 HPC 应用程序框架:
我不知道 MOOSE 如何使用 TBB,但 MADNESS 使用 TBB 作为其任务队列和内存分配器。
我个人在Parallel Research Kernels项目中使用了 TBB,在其中我将 TBB 与 OpenMP、OpenCL、Kokkos、RAJA、C++17 Parallel STL 和其他模型进行了比较。有关详细信息,请参见C++ 子目录。
下图显示了上述型号在 Intel Xeon Phi 7250 处理器上的相对性能(细节并不重要 - 所有型号都使用相同的设置)。正如你所看到的,除了较小的问题规模之外,TBB 做得很好,自适应调度的开销更相关。TBB 具有会影响这些结果的调谐旋钮。
全面披露:我为英特尔工作,从事研究/寻路工作。
ZThread 是 LGPL,如果不在开源项目中工作,您只能在动态链接中使用该库。
开源版本中的线程构建块(TBB),(有一个新的商业版本,299 美元,还不知道有什么区别)是带有所谓“运行时异常”的 GNU 通用公共许可证版本 2 (即特定于仅用于创建免费软件。)
我已经看到其他运行时异常尝试接近 LGPL,但启用商业用途和静态链接现在不是 这种情况。
我之所以写这篇文章,是因为我借此机会检查了库许可证,并且这些许可证也应该是根据打算给予它们的用途进行选择的考虑因素。
Txs,Jihn 指出此更新...
我已经简单地使用过 TBB,并且将来可能会更多地使用它。我喜欢使用它,最重要的是因为您不必处理 C++ 的宏/扩展,而是保留在语言中。它也非常便携。我在windows和linux上都用过。但是有一件事:使用 TBB 处理线程很困难,您必须从任务的角度来考虑(这实际上是一件好事)。英特尔 TBB 不支持您使用裸锁(这会使这变得乏味)。但总的来说,这是我的初步经验。
我还建议您也看看 openMP 3。
我在一个项目中使用 TBB。它似乎比线程更容易使用。有些任务可以并行运行。任务只是对并行子例程的调用。负载平衡是自动完成的。这就是为什么我接受它作为更高级别的并行化库。我在 4 核英特尔处理器上没有太多工作就实现了 2.5 倍的速度。有一些例子,他们在论坛上回答问题,并且它被维护并且它是免费的。
与其他替代方案(例如 C++ 11x 并发特性)相比,TBB(线程构建块)的用途值得明确。TBB 是一个可移植和可扩展的库(不是编译器扩展),允许您以轻量级任务的形式编写代码,TBB 将安排这些任务在可用的 CPU 资源上尽可能快地运行。它不是为其他目的(例如抢占)而设计的支持线程。
我使用 TBB 将图像扫描线上的 for 循环的现有图像处理加速到 parallel_for 循环中(至少 2-4 条扫描线作为“粒度”大小)。这是非常成功的。它确实需要(重新)编写循环体以处理任意索引,而不是假设每个循环体都是按顺序处理的(例如,在每次循环迭代之间递增的指针)。
这是一个相当简单的案例,因为没有要更新的共享存储。使用更强大的功能(例如管道)将需要大量重新构想和/或重写现有代码,因此可能更适合新代码。
这个基于 TBB 的代码保持可移植性是一个强大的优势,似乎不会干扰同一进程中的其他代码同时使用其他线程策略,并且以后可以与更高或更低级别的多处理策略(例如 TBB parallel_for代码可以从 TBB 多处理管道中的过滤器调用)。
我研究过 TBB,但从未在项目中使用过它。我没有看到比ZThread有任何优势(出于我的目的)。可以在此处找到简短且有些过时的概述。
它相当完整,有几个线程调度选项、所有常用的同步类和一个非常方便的基于异常的线程“中断”机制。它易于扩展,编写良好且有文档记录。我已经在 20 多个项目中使用了它。
它还可以与任何支持 POSIX 线程以及 Windows 的 *NIX 配合使用。
值得一看。
开源版本中的 Threading Building Blocks (TBB),(有一个新的商业版本,299 美元,还不知道有什么区别)是带有所谓“运行时异常”的 GNU 通用公共许可证版本 2(即特定于仅在创建免费软件时使用。)我已经看到其他尝试接近 LGPL 但启用商业使用和静态链接的运行时异常,情况并非如此。
根据这个问题,线程构建块可以在没有版权限制的情况下用于商业用途。