C++ 并行化库:OpenMP 与线程构建块 [关闭]

Posted

技术标签:

【中文标题】C++ 并行化库:OpenMP 与线程构建块 [关闭]【英文标题】:C++ Parallelization Libraries: OpenMP vs. Thread Building Blocks [closed] 【发布时间】:2009-03-05 15:28:55 【问题描述】:

我将改进我的自定义图形引擎,以便它能够利用多核 CPU。更确切地说,我正在寻找一个库来并行化循环。

在我看来,OpenMP 和英特尔的线程构建模块都非常适合这项工作。此外,Visual Studio 的 C++ 编译器和大多数其他流行的编译器都支持两者。这两个库似乎都非常易于使用。

那么,我应该选择哪一个?有没有人尝试过这两个库,并且可以给我一些使用这两个库的利弊?另外,你最终选择了与什么合作?

谢谢,

阿德里安

【问题讨论】:

类似问题:***.com/questions/326487/…(我在我的问题中添加了对这个问题的引用。) 【参考方案1】:

我没有广泛使用 TBB,但我的印象是它们相互补充而不是竞争。 TBB 提供线程安全容器和一些并行算法,而 OpenMP 更多的是一种并行化现有代码的方法。

就我个人而言,我发现 OpenMP 很容易放入现有代码中,您可以在其中有一个可并行化的循环或一堆可以并行运行的部分。但是,对于您需要修改一些共享数据的情况,它对您没有帮助——TBB 的并发容器可能正是您想要的。

如果您只想并行化迭代独立的循环(或者可以相当容易地做到这一点),我会选择 OpenMP。如果您需要线程之间的更多交互,我认为 TBB 在这方面可能会提供更多。

【讨论】:

关于现有代码的要点。在这里和那里插入一些 pragma 更容易。插入 TBB 可能会更困难(很大程度上取决于现有的代码风格)【参考方案2】:

来自英特尔的软件博客:Compare Windows* threads, OpenMP*, Intel® Threading Building Blocks for parallel programming

这也是风格的问题 - 对我来说,TBB 非常像 C++,而我不太喜欢 OpenMP 编译指示(有点 C 的味道,如果我必须用 C 编写,我会使用它)。

我还会考虑团队现有的知识和经验。学习一个新库(尤其是在线程/并发方面)确实需要一些时间。我认为目前,OpenMP 比 TBB 更广为人知和部署(但这只是我的观点)。

还有一个因素——但考虑到最常见的平台,可能不是问题——可移植性。但是许可证可能是个问题。

TBB 包含了一些源自学术研究的优秀研究,例如 recursive data parallel approach。 example 在缓存友好性方面做了一些工作。 英特尔博客的讲座似乎很有趣。

【讨论】:

感谢您的链接,但由于它托管在英特尔的网站上,因此我不会真正相信它会提供完全公正的意见。显然,他们写这篇文章是为了宣传他们自己的图书馆的使用。 是的,在第一行的某处忘记了表情符号;)【参考方案3】:

总的来说,我发现使用 TBB 需要对代码库进行更耗时的更改,并带来高回报,而 OpenMP 提供快速但适中的回报。如果您正在从头开始关注一个新模块并考虑长期考虑,请选择 TBB。如果您想要小而直接的收益,请选择 OpenMP。

此外,TBB 和 OpenMP 并不相互排斥。

【讨论】:

【参考方案4】:

我实际上都使用过这两种方法,我的总体印象是,如果您的算法相当容易实现并行化(例如,大小均匀的循环,没有太多的数据相互依赖性),OpenMP 更容易,而且很好用。事实上,如果您发现可以使用 OpenMP,那么如果您知道您的平台会支持它,这可能是更好的选择。我没有使用过 OpenMP 的新任务结构,它比原来的循环和部分选项更通用。

TBB 预先为您提供了更多的数据结构,但肯定需要更多的预先准备。另外,它可能更能让您了解竞争条件错误。我的意思是,在 OpenMP 中通过不共享(或其他)应该共享的东西来启用竞争条件是相当容易的。只有当你得到不好的结果时,你才会看到这一点。我认为 TBB 不太可能发生这种情况。

总的来说,我个人更喜欢 OpenMP,尤其是考虑到它在任务方面的表现力更强。

【讨论】:

【参考方案5】:

据我所知,TBB(有一个可用的 GPLv2 下的开源版本)更关注 C++ 而非 C 领域。这些时候很难找到 C++ 和通用 OOP 并行化特定信息。大多数地址功能性的东西,如 c(在 CUDA 或 OpenCL 上相同)。如果您需要 C++ 对并行化的支持,请选择 TBB!

【讨论】:

TBB 现在使用 Apache 许可证...【参考方案6】:

是的,TBB 对 C++ 更友好,而鉴于其设计,OpenMP 更适合 FORTRAN 风格的 C 代码。 OpenMP 中的新任务功能看起来很有趣,同时 C++0x 中的 Lambda 和函数对象可能会使 TBB 更易于使用。

【讨论】:

【参考方案7】:

在 Visual Studio 2008 中,您可以添加以下行来并行化任何“for”循环。它甚至可以与多个嵌套的 for 循环一起使用。这是一个例子:

#pragma omp parallel for private(i,j)
for (i=0; i<num_particles; i++)

  p[i].fitness = fitnessFunction(p[i].present);
  if (p[i].fitness > p[i].pbestFitness)
   
     p[i].pbestFitness = p[i].fitness;
     for (j=0; j<p[i].numVars; j++) p[i].pbest[j] = p[i].present[j];
  
  
gbest = pso_get_best(num_particles, p);

在我们添加 #pragma omp parallel 后,我的 Core 2 Duo 上的两个内核都使用了最大容量,因此总 CPU 使用率从 50% 上升到 100%。

【讨论】:

请注意:嵌套循环只有在编译器支持时才有效 另外注意:您可以使用omp parallel for 并行化任何 parallelizable for 循环。例如,如果正文包含如下代码,则不能使用 omp parallel forp[j] = p[j] - p[j-1]

以上是关于C++ 并行化库:OpenMP 与线程构建块 [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

在 Openmp (C++) 中销毁线程

OpenMP 并行等待

C++ openmp并行程序在多核linux上如何最大化使用cpu

在 C++ OpenMP 中为每个线程定义一个优先级队列

在 C++ 中使用 OpenMP 并行化算法

并行任务中的 C++ OpenMP 变量可见性