为什么英特尔线程构建模块(TBB)parallel_for
有如此大的开销?根据{{1}}中的第3.2.2节自动分块,大约半毫秒。这是教程中的一个重点:
注意:通常一个循环需要至少一百万个时钟 parallel_for的循环以改善其性能。例如,a 在2 GHz处理器上至少需要500微秒的循环可能 受益于parallel_for。
从我到目前为止所读到的内容,TBB在内部使用了线程池(工作线程池)模式,它通过最初只生成工作线程(这需要数百微秒)来防止这种不良开销。
那是什么花时间?使用互斥锁进行数据同步并不是那么慢吗?此外,TBB不使用无锁数据结构进行同步吗?
答案 0 :(得分:11)
从我到目前为止所读到的内容,TBB在内部使用了线程池(工作线程池)模式,它通过最初生成工作线程(这需要花费数百微秒)来防止这种糟糕的开销。
是的,TBB预先分配线程。只要看到parallel_for
,它就不会在物理上创建和连接工作线程。 OpenMP和其他并行库都进行预分配。
但是,从池中唤醒线程并将逻辑任务分配给线程仍然存在开销。是的,TBB利用无锁数据结构来最小化开销,但它仍然需要一些并行开销(即串行部分)。这就是为什么TBB手册建议避免非常短的循环。
通常,您必须有足够的工作才能获得并行加速。我认为即使是1毫秒(= 1,000微秒)也太小了。根据我的经验,为了看到有意义的加速,我需要将执行时间增加大约100毫秒。
如果您真正担心TBB parallel_for
的并行开销,那么尝试简单的静态调度可能是值得的。我不太了解TBB的静态调度实现。但是,您可以轻松尝试OpenMP的一个:omp parallel for schedule(static)
。我相信这个开销将是并行的最小成本。但是,由于它使用静态调度,动态调度的好处(特别是当工作负载不均匀时)将会丢失。