TBB 线程池意外增加

Posted

技术标签:

【中文标题】TBB 线程池意外增加【英文标题】:TBB thread pool unexpectedly increasing 【发布时间】:2016-06-24 13:52:12 【问题描述】:

我们有一段代码利用 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 不应该将工作线程的数量固定为等于内核的数量吗?

【问题讨论】:

是否有可能在 TBB 外部创建线程?线程是一种系统资源,程序的任何其他部分都可以创建它们。 如果你new-编辑了task,你在哪里delete呢? 【参考方案1】:

正如我在另一个回答中所说的那样:别担心 :-)

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

TBB 尽可能减少了此数据争用的窗口,但要完全关闭它,需要在热路径上进行同步,这会影响总体性能。因此,我们决定允许数据竞争并减少热路径上的障碍。

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

不过,我很惊讶它创建了 15 个线程,而且我理解您的担忧。如果您与他们共享复制器,TBB 团队将不胜感激。您可以通过TBB Forum 或OSS site 贡献复制者。

【讨论】:

感谢您的帮助,但我们有几个后续问题。 1.什么是复制器。 2.我们如何创建并提交? @S.J.Thunderstick 复制器是重现问题的最小测试。您创建测试并将其发布在论坛上或作为贡献发布。但同样,这并不是什么大问题——既不是泄漏也不是超额订阅

以上是关于TBB 线程池意外增加的主要内容,如果未能解决你的问题,请参考以下文章

线程池小计

如何在 asp.net Core 中增加最大线程池限制

线程池

如何增加tomcat线程池中的线程数?

.NET Framework 和 .NET Core 之间的线程池差异,线程池饥饿

SimpleThreadPool给线程池增加自动扩充线程数量,以及闲时自动回收的功能