1

这是示例代码:

#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),但只调用了第一个和第二个任务。这是被盯上了?

4

2 回答 2

4

是的,这是预期的行为。

TBB 是一个旨在为性能并行化代码的库。它不是为异步任务设计的——官方文档声明你应该使用另一个库,例如 pthreads,来处理这些任务(或者你的情况下是 boost::thread)。

为了获得最佳性能,拥有比内核更多的线程没有任何意义,因为涉及一些重大开销(不仅是上下文切换,还包括刷新缓存之类的事情)。

编辑:您可以在教程中阅读它。具体来说,在第 1.2 节“好处”中指出

英特尔® 线程构建模块以线程为目标,以提高性能。大多数通用线程包支持许多不同类型的线程,例如图形用户界面中的异步事件线程。因此,通用包往往是提供基础的低级工具,而不是解决方案。相反,英特尔® 线程构建模块专注于并行化计算密集型工作的特定目标,提供更高级别、更简单的解决方案。

英特尔® 线程构建模块与其他线程包兼容。由于该库并非旨在解决所有线程问题,因此它可以与其他线程包无缝共存。

于 2010-11-22T16:25:57.823 回答
1

大规模多线程阻塞行为(std::cout 使用)是多线程中的反模式,可能会导致不良行为,因为这是错误的做法。此外,TBB 保留执行 group.run() 的权利,不管它喜欢什么,并产生它喜欢的任何线程。如果你只有一个双核,而且你调用繁重的工作,为什么它应该产生两个以上的线程?操作系统和其他应用程序将愉快地吃掉剩余的后台时间。

于 2010-08-03T13:21:56.257 回答