TBB线程池意外增加

时间:2016-06-24 13:52:13

标签: c++ tbb

我们有一段代码利用TBB生成任务来执行某些处理,这是使用以下TBB代码来初始化TBB线程池完成的:

tbb::task_scheduler_init(8);

然后,对于我们想要生成的每个任务,我们使用以下代码(其中MainTask派生自tbb :: task类):

task = new (tbb::task::allocate_root()) MainTask(theAction, theOutputData);
tbb::task::enqueue(*task);

当我们运行我们的代码时,我们开始使用一个与预期的内核数量(在我们的例子中是8个线程)相同的线程池,但是当程序执行并产生新的TBB任务时,如上所述,数字一些随机点的线程突然增加。程序执行40分钟后,线程数从8增加到15之间。

为什么会这样? TBB是否应该将固定的工作线程数保持为等于核心数?

1 个答案:

答案 0 :(得分:1)

正如我在另一个回答中所说:不要担心: - )

TBB在防止实际超额预订方面做得很好 - 同时只有8个线程在您的程序中处于活动状态。虽然由于各种原因,它有时需要比硬件资源更多的线程。一个示例是tbb::task_arena,没有保留主插槽,另一个最近添加的是tbb::global_control类,它允许动态更改池中活动线程的数量。不幸的是,TBB如​​何实现它的方式为数据竞争留下了一些空间。当一些线程返回到线程池以便在新工作到达时获得一些睡眠并且请求所有8个线程立即开始处理时,就会发生这种情况。但是处于中间状态的这些线程尚未计入线程池,而是创建新线程。

TBB尽可能地减少了此数据竞争的窗口,但要完全关闭它,热路径上需要同步,这将影响一般性能。因此,决定允许数据竞争并在热门路径上减少障碍。

但是,不用担心,没有资源泄漏,因为TBB对这种方式可以创建的最大线程数有硬性限制。根据平台的不同,这个数字会从2x到4x不等(尽管它的内部实现细节会不断变化)。

尽管如此,我很惊讶它创造了15个线程并且我理解你的担忧。如果您与他们共享复制器,TBB团队将非常感激。您可以通过TBB ForumOSS site提供复制器。