TBB线程池意外增加
TBB thread pool unexpectedly increasing
我们有一段代码,利用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在防止实际的过度订阅方面做得很好-同时只有8个线程将在您的程序中处于活动状态。尽管由于各种原因,它有时需要比硬件资源更多的线程。一个例子是没有保留主槽的tbb::task_arena
,另一个最近增加的是tbb::global_control
类,它允许动态更改池中活动线程的数量。不幸的是,TBB实现它的方式为数据竞争留下了一些空间。当一些线程在返回线程池的路上获得一些睡眠时,当一个新工作到达并请求所有8个线程立即开始处理时,就会发生这种情况;但是这些处于中间状态的线程还没有被计算在线程池中,而是创建了新的线程。
TBB尽可能地减少了这个数据竞争的窗口,但是要完全关闭它,需要在热路径上进行同步,这将影响总体性能。因此,我们决定允许数据竞争,并在热路径上设置更少的障碍。
但是,不要担心,没有资源泄漏,因为TBB对这种方式可以创建的最大线程数量有硬限制。根据不同的平台,这个数字从2倍到4倍不等(尽管它的内部实现细节在不断变化)。
虽然,我很惊讶,它走了这么远的15线程创建,我理解你的担忧。如果你与TBB团队分享一个复制器,他们会很感激的。您可以通过TBB论坛或OSS网站提供复制器。
- 数组索引的值没有增加
- 为什么我的代码在输出中增加了93天
- 在C++中对T*类型执行std::move的意外行为
- 有效地使用std::unordered_map来插入或增加键的值
- 使用取消引用的指针的多态性会产生意外的结果.为什么?
- 处理除以零会导致<csignal>意外行为
- vscode下的Arduino代码出现意外编译错误
- 使用++运算符会导致意外的结果
- 套接字读取后,我在缓冲区中看到意外输入
- 更改.cpp程序的输入文件中数据的位置会意外更改输出
- C++ 动态数组每次添加时将大小增加 1 - 错误
- 为什么要增加导致崩溃的指针
- 使用vscode调试时,GDB意外退出
- 此测试()中发生了什么意外过程?为什么总是覆盖 ch[0 1 2..]?
- 尝试将字符串/字符转换为整数会产生意外结果
- 错误 C2760:语法错误:映射迭代器上意外的标记"标识符",预期的";"
- C++标头错误 C2238 意外标记";"
- C++中意外的多头值
- 在数组中增加元素时进程意外终止
- TBB线程池意外增加