scooterman
scooterman

Reputation: 1346

Tasks on Thread Building Blocks

Here is the example code:

#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);
}

Here I'm computing a big fibonacci sequence just to simulate non-blocking computation. I was specting that this code would generate more than two threads (my computer is a Core2Duo), but only the first and second tasks are called. This is the spected?

Upvotes: 1

Views: 5225

Answers (2)

user21037
user21037

Reputation:

Yes, this is the expected behavior.

TBB is a library designed to parallelize code for PERFORMANCE. It is not designed for asynchronous tasks - the official documentation states that you should use another library, eg pthreads, for such tasks (or boost::thread, in your case).

For maximum performance, it does not make any sense to have more threads than you do cores, as there are some significant overheads involved (not just context switching, but also things like flushing the cache).

EDIT: You can read about it in the Tutorial. Specifically, in section 1.2 "Benefits" it states

Intel® Threading Building Blocks targets threading for performance. Most general-purpose threading packages support many different kinds of threading, such as threading for asynchronous events in graphical user interfaces. As a result, general-purpose packages tend to be low-level tools that provide a foundation, not a solution. Instead, Intel® Threading Building Blocks focuses on the particular goal of parallelizing computationally intensive work, delivering higher-level, simpler solutions.

and

Intel® Threading Building Blocks is compatible with other threading packages. Because the library is not designed to address all threading problems, it can coexist seamlessly with other threading packages.

Upvotes: 4

Puppy
Puppy

Reputation: 146910

Massively multithreading blocking behaviour (std::cout use) is an anti-pattern in multithreading and may result in bad behaviour, because it's the wrong thing to do. In addition, TBB reserves the right to implement group.run() however the hell it likes and spawn whatever threads it likes. If you only have a dual core, and you call with heavy work, why should it spawn more than two threads? The OS and other apps will happily eat remaining background time.

Upvotes: 1

Related Questions