以下是示例代码:
#include <iostream>
#include <list>
#include <tbb/task.h>
#include <tbb/task_group.h>
#include <stdlib.h>
#include <boost/thread.hpp>
using namespace tbb;
long fib(long a)
{
if (a < 2) return 1;
return fib(a - 1) + fib(a - 2);
}
class PrintTask
{
public:
void operator()()
{
std::cout << "hi world!: " << boost::this_thread::get_id() << std::endl;
fib(50);
}
};
int main(int argc, char** argv)
{
task_group group;
for (int i = 0; i < 100; ++i)
{
group.run(PrintTask());
}
group.wait();
return(0);
}
这里我正在计算一个大的斐波那契序列,只是为了模拟非阻塞计算。我说这个代码会生成两个以上的线程(我的计算机是Core2Duo),但只调用第一个和第二个任务。这是指定的?
答案 0 :(得分:3)
是的,这是预期的行为。
TBB是一个用于并行化PERFORMANCE代码的库。它不是为异步任务设计的 - 官方文档声明你应该使用另一个库,例如pthreads来完成这些任务(或者你的情况下使用boost :: thread)。
为了获得最佳性能,拥有比核心更多的线程没有任何意义,因为涉及一些重要的开销(不仅仅是上下文切换,还有刷新缓存等)。
编辑: 您可以在Tutorial中阅读相关内容。具体来说,在第1.2节“福利”中说明了
英特尔®线程构建模块旨在提高性能。 大多数通用线程包支持许多不同类型 线程化,例如图形用户中异步事件的线程化 接口。因此,通用包往往是 提供基础的低级工具,而不是解决方案。代替, 英特尔®线程构建模块专注于特定的目标 并行计算密集型工作,交付 更高层次,更简单的解决方案。
和
英特尔®线程构建模块与其他线程兼容 包。因为该库不是为解决所有线程问题而设计的, 它可以与其他线程包无缝共存。
答案 1 :(得分:1)
大规模多线程阻塞行为(std :: cout use)是多线程中的反模式,可能导致不良行为,因为这是错误的做法。此外,TBB保留实施group.run()的权利,但它喜欢它并产生它喜欢的任何线程。如果你只有一个双核心,而你的工作繁重,为什么它会产生两个以上的线程呢?操作系统和其他应用程序将很乐意吃掉剩余的后台时间。