我将改造我的自定义图形引擎,以便它能够利用多核 CPU。更确切地说,我正在寻找一个库来并行化循环。
在我看来,OpenMP 和英特尔的线程构建块都非常适合这项工作。此外,Visual Studio 的 C++ 编译器和大多数其他流行的编译器都支持两者。这两个库似乎都非常易于使用。
那么,我应该选择哪一个呢?有没有人尝试过这两个库,并且可以给我一些使用这两个库的利弊?另外,你最终选择了与什么合作?
谢谢,
阿德里安
我将改造我的自定义图形引擎,以便它能够利用多核 CPU。更确切地说,我正在寻找一个库来并行化循环。
在我看来,OpenMP 和英特尔的线程构建块都非常适合这项工作。此外,Visual Studio 的 C++ 编译器和大多数其他流行的编译器都支持两者。这两个库似乎都非常易于使用。
那么,我应该选择哪一个呢?有没有人尝试过这两个库,并且可以给我一些使用这两个库的利弊?另外,你最终选择了与什么合作?
谢谢,
阿德里安
我没有广泛使用 TBB,但我的印象是它们相互补充而不是竞争。TBB 提供线程安全容器和一些并行算法,而 OpenMP 更多的是一种并行化现有代码的方法。
就我个人而言,我发现 OpenMP 很容易放入现有代码中,您可以在其中有一个可并行化的循环或一堆可以并行运行的部分。但是,对于需要修改一些共享数据的情况,它对您没有帮助——TBB 的并发容器可能正是您想要的。
如果您想要的只是并行化迭代独立的循环(或者可以很容易地做到这一点),我会选择 OpenMP。如果您需要线程之间的更多交互,我认为 TBB 在这方面可能会提供更多。
来自英特尔的软件博客:比较 Windows* 线程、OpenMP*、英特尔® 线程构建块以进行并行编程
这也是风格的问题——对我来说,TBB 非常像 C++,而我不太喜欢 OpenMP 编译指示(有点 C 的味道,如果我必须用 C 编写,我会使用它)。
我也会考虑团队现有的知识和经验。学习一个新库(尤其是在线程/并发方面)确实需要一些时间。我认为目前,OpenMP 比 TBB 更广为人知和部署(但这只是我的观点)。
还有一个因素——但考虑到最常见的平台,可能不是问题——可移植性。但是许可证可能是个问题。
总的来说,我发现使用 TBB 需要对代码库进行更耗时的更改并获得高回报,而 OpenMP 提供快速但适中的回报。如果您正在从头开始关注新模块并考虑长期考虑,请选择 TBB。如果您想要小而直接的收益,请选择 OpenMP。
此外,TBB 和 OpenMP 并不相互排斥。
我实际上都使用过这两种方法,我的总体印象是,如果您的算法相当容易实现并行(例如,大小均匀的循环,没有太多的数据相互依赖性),OpenMP 更容易,而且很好用。事实上,如果您发现自己可以使用 OpenMP,如果您知道您的平台会支持它,这可能是更好的选择。我没有使用过 OpenMP 的新任务结构,它比原来的循环和部分选项更通用。
TBB 预先为您提供了更多的数据结构,但肯定需要更多的预先准备。另外,它可能会更好地让您了解竞争条件错误。我的意思是,在 OpenMP 中通过不共享(或其他)应该共享的东西来启用竞争条件是相当容易的。只有当你得到不好的结果时,你才会看到这一点。我认为 TBB 不太可能发生这种情况。
总的来说,我个人偏爱 OpenMP,尤其是考虑到它在任务方面的表现力更强。
据我所知,TBB(有一个可用的 GPLv2 下的开源版本)更关注 C++,然后是 C 领域。这些时候很难找到 C++ 和一般的 OOP 并行化特定信息。大多数地址功能性的东西,如 c(在 CUDA 或 OpenCL 上相同)。如果您需要 C++ 支持并行化,请选择 TBB!
是的,TBB 对 C++ 更友好,而鉴于其设计,OpenMP 更适合 FORTRAN 风格的 C 代码。OpenMP 中的新任务功能看起来很有趣,同时 C++0x 中的 Lambda 和函数对象可能会使 TBB 更易于使用。
在 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%。