Intel TBB Parallelization Overhead

4
为什么Intel Threading Building Blocks (TBB)的parallel_for有如此大的开销?根据Tutorial.pdf中3.2.2节的《自动分块》,它大约需要半毫秒。以下是教程中的一段引用:
“注意:通常一个循环至少需要花费100万个时钟周期,才能使parallel_for提高性能。例如,在2 GHz处理器上,需要至少500微秒的循环才能从parallel_for中受益。”
据我所了解,TBB在内部使用线程池(工作线程池)模式,并通过仅在最初生成工作线程时(这需要数百微秒)来防止此类糟糕的开销。
那么时间去哪里了?使用互斥锁进行数据同步不会很慢吧?此外,TBB是否使用无锁数据结构进行同步?
1个回答

12
据我所读,TBB内部使用线程池(工作线程池)模式,并通过最初只生成一次工作线程(需要数百微秒)来防止此类糟糕的开销。
是的,TBB预先分配线程。它不会在每次看到parallel_for时物理创建和加入工作线程。OpenMP和其他并行库都进行预分配。
但是,仍然需要唤醒来自线程池的线程并将逻辑任务分派给线程,会有一些开销。是的,TBB利用无锁数据结构来最小化开销,但仍需要一定量的并行开销(即串行部分)。这就是为什么TBB手册建议避免使用非常短的循环的原因。
通常,必须有足够的工作才能获得并行加速。我认为即使1毫秒(= 1,000微秒)也太少了。根据我的经验,为了看到有意义的加速,我需要将执行时间增加到约100毫秒左右。
如果您真的关心TBB parallel_for的并行开销,尝试简单的静态调度可能是值得的。我对TBB的静态调度实现不是很了解。但是,您可以轻松尝试OpenMP的一个:`omp parallel for schedule(static)`。我相信这种开销将是并行for中最小的成本。但是,由于它使用静态调度,因此将失去动态调度的好处(特别是在工作负载不均匀时)。

谢谢!TBB看起来很棒,设计得很好!然而,我有点不确定如何解释你在回答中的前两句话:1. OpenMP和其他并行库是否预分配线程?2. 与OpenMP和libstdc++并行模式相比,主要差异是什么?你能推荐一个可以解释这个问题的比较网页吗? - Nordlöw
是的,它们大多数都是预分配的。不过实际上这取决于具体的实现方式。 - minjang
1
  1. libstdc++ 并行模式是否意味着 pthread?OpenMP 作为编译器中间层实现(与 TBB 的纯 C++ 库方法相对),提供了一种简单的方式来实现 parallel-for,具有较小的并行开销。但是,它不像 Cilk、TBB 中的工作窃取那样提供良好的动态调度器。
- minjang

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