我要改造自定义图形引擎,以便利用多核CPU。更确切地说,我正在寻找一个并行化循环的库。
在我看来,OpenMP和英特尔的Thread Building Blocks都非常适合这项工作。此外,Visual Studio的C ++编译器和大多数其他流行的编译器都支持它们。这两个库看起来都非常简单易用。
那么,我应该选择哪一个?有没有人尝试过两个库,可以给我一些利弊和使用任何一个库的优点?另外,你最终选择了什么?
谢谢,
阿德里安
答案 0 :(得分:46)
我没有广泛使用TBB,但我的印象是,它们相互补充而不是竞争。 TBB提供线程安全容器和一些并行算法,而OpenMP更像是一种并行化现有代码的方法。
就我个人而言,我发现OpenMP非常容易放入现有的代码中,在这些代码中你有一个可并行运行的并行循环或一系列部分。但是,对于需要修改某些共享数据的情况,它并没有帮助 - TBB的并发容器可能正是您想要的。
如果您想要的是并行化迭代独立的循环(或者可以相当容易地进行),我会选择OpenMP。如果您需要在线程之间进行更多交互,我认为TBB可能会在这方面提供更多的内容。
答案 1 :(得分:25)
来自英特尔的软件博客:Compare Windows* threads, OpenMP*, Intel® Threading Building Blocks for parallel programming
这也是风格的问题 - 对我来说,TBB非常像C ++,而我不喜欢OpenMP pragma那么多(如果我不得不用C语言编写,那么就会使用它)。
我还会考虑团队的现有知识和经验。学习一个新的库(特别是涉及到线程/并发)确实需要一些时间。我认为,就目前而言,OpenMP比TBB更广为人知和部署(但这只是我的意见)。
另一个因素 - 但考虑到最常见的平台,可能不是问题 - 可移植性。但许可证可能是一个问题。
答案 2 :(得分:16)
总的来说,我发现使用TBB需要更长时间的代码库更改,并且收益高,而OpenMP可以提供快速但适度的支付。如果你从头开始盯着一个新的模块,并考虑与TBB长期合作。如果您希望获得小的但立即获得的收益,请使用OpenMP。
此外,TBB和OpenMP不是互斥的。
答案 3 :(得分:6)
我实际上使用了两者,我的总体印象是,如果您的算法很容易并行(例如,大小均匀的循环,而不是太多的数据相互依赖),OpenMP更容易,并且非常适合使用。事实上,如果您发现可以使用OpenMP,那么它可能是更好的方法,如果您知道您的平台将支持它。我没有使用OpenMP的新任务结构,它比原始循环和部分选项更通用。
TBB预先为您提供更多数据结构,但绝对需要更多预先。作为一个加号,它可能更好地让你意识到竞争条件错误。我的意思是,在OpenMP中通过不创建共享(或其他任何东西)来实现竞争条件是相当容易的。只有当你得到不好的结果时才会看到这个。我认为这与TBB相比不太可能发生。
总的来说,我个人倾向于OpenMP,特别是考虑到其对任务的表现力增强。
答案 4 :(得分:2)
Viva64链接:Parallel Programming。
答案 5 :(得分:2)
是的,TBB对C ++更加友好,而OpenMP更适合FORTRAN风格的C代码,因为它的设计。 OpenMP中的新任务功能看起来非常有趣,同时C ++ 0x中的Lambda和函数对象可以使TBB更易于使用。
答案 6 :(得分:1)
在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%。
答案 7 :(得分:1)
据我所知,TBB(在GPLv2下有一个OpenSource版本)可以更多地使用C ++,然后是C区。这些时候很难找到C ++和一般OOP并行化特定的信息。最常用的功能是像c(在CUDA或OpenCL上相同)。如果您需要C ++支持并行化,请转到TBB!