Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Simplest TBB example

Tags:

Can someone give me a TBB example how to:

  1. set the maximum count of active threads.
  2. execute tasks that are independent from each others and presented in the form of class, not static functions.
like image 379
Nelson Tatius Avatar asked May 15 '12 19:05

Nelson Tatius


1 Answers

Here's a couple of complete examples, one using parallel_for, the other using parallel_for_each.

Update 2014-04-12: These show what I'd consider to be a pretty old fashioned way of using TBB now; I've added a separate answer using parallel_for with a C++11 lambda.

#include "tbb/blocked_range.h"
#include "tbb/parallel_for.h"
#include "tbb/task_scheduler_init.h"
#include <iostream>
#include <vector>

struct mytask {
  mytask(size_t n)
    :_n(n)
  {}
  void operator()() {
    for (int i=0;i<1000000;++i) {}  // Deliberately run slow
    std::cerr << "[" << _n << "]";
  }
  size_t _n;
};

struct executor
{
  executor(std::vector<mytask>& t)
    :_tasks(t)
  {}
  executor(executor& e,tbb::split)
    :_tasks(e._tasks)
  {}

  void operator()(const tbb::blocked_range<size_t>& r) const {
    for (size_t i=r.begin();i!=r.end();++i)
      _tasks[i]();
  }

  std::vector<mytask>& _tasks;
};

int main(int,char**) {

  tbb::task_scheduler_init init;  // Automatic number of threads
  // tbb::task_scheduler_init init(2);  // Explicit number of threads

  std::vector<mytask> tasks;
  for (int i=0;i<1000;++i)
    tasks.push_back(mytask(i));

  executor exec(tasks);
  tbb::parallel_for(tbb::blocked_range<size_t>(0,tasks.size()),exec);
  std::cerr << std::endl;

  return 0;
}

and

#include "tbb/parallel_for_each.h"
#include "tbb/task_scheduler_init.h"
#include <iostream>
#include <vector>

struct mytask {
  mytask(size_t n)
    :_n(n)
  {}
  void operator()() {
    for (int i=0;i<1000000;++i) {}  // Deliberately run slow
    std::cerr << "[" << _n << "]";
  }
  size_t _n;
};

template <typename T> struct invoker {
  void operator()(T& it) const {it();}
};

int main(int,char**) {

  tbb::task_scheduler_init init;  // Automatic number of threads
  // tbb::task_scheduler_init init(4);  // Explicit number of threads

  std::vector<mytask> tasks;
  for (int i=0;i<1000;++i)
    tasks.push_back(mytask(i));

  tbb::parallel_for_each(tasks.begin(),tasks.end(),invoker<mytask>());
  std::cerr << std::endl;

  return 0;
}

Both compile on a Debian/Wheezy (g++ 4.7) system with g++ tbb_example.cpp -ltbb (then run with ./a.out)

(See this question for replacing that "invoker" thing with a std::mem_fun_ref or boost::bind).

like image 159
timday Avatar answered Sep 19 '22 19:09

timday