C++ 最简单的 TBB 示例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10607215/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:16:18  来源:igfitidea点击:

Simplest TBB example

c++tbbicc

提问by Jofsey

Can someone give me a TBBexample how to:

有人可以给我一个TBB示例如何:

  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.
  1. 设置活动线程的最大计数。
  2. 执行相互独立并以类的形式呈现的任务,而不是静态函数。

回答by timday

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

这里有几个完整的例子,一个使用parallel_for,另一个使用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 answerusing parallel_forwith a C++11 lambda.

2014 年 4 月 12 日更新:这些展示了我认为现在使用 TBB 的一种非常老式的方式;我使用C++11 lambda添加了一个单独的答案parallel_for

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

两者都在 Debian/Wheezy (g++ 4.7) 系统上编译g++ tbb_example.cpp -ltbb(然后使用./a.out

(See this questionfor replacing that "invoker" thing with a std::mem_fun_refor boost::bind).

(请参阅此问题以将“ invoker” 事物替换为std::mem_fun_refboost::bind)。

回答by timday

Here's a more modern use of parallel_forwith a lambda; compiles and runs on Debian/Wheezy with g++ -std=c++11 tbb_example.cpp -ltbb && ./a.out:

这是一个更现代parallel_for的 lambda用法;在 Debian/Wheezy 上编译并运行g++ -std=c++11 tbb_example.cpp -ltbb && ./a.out

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

int main(int,char**) {

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

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

  tbb::parallel_for(
    tbb::blocked_range<size_t>(0,tasks.size()),
    [&tasks](const tbb::blocked_range<size_t>& r) {
      for (size_t i=r.begin();i<r.end();++i) tasks[i]();
    }
  );

  std::cerr << std::endl;

  return 0;
}

回答by pingul

If you just want to run a couple of tasks concurrently, it might be easier to just use a tbb::task_group. Example taken from tbb:

如果您只想同时运行几个任务,使用tbb::task_group. 取自tbb 的示例

#include "tbb/task_group.h"  

using namespace tbb;

int Fib(int n) {
    if( n<2 ) {
        return n;
    } else {
        int x, y;
        task_group g;
        g.run([&]{x=Fib(n-1);}); // spawn a task
        g.run([&]{y=Fib(n-2);}); // spawn another task
        g.wait();                // wait for both tasks to complete
        return x+y;
    }
}

Note however that

但是请注意

Creating a large number of tasks for a single task_group is not scalable, because task creation becomes a serial bottleneck.

为单个 task_group 创建大量任务是不可扩展的,因为任务创建成为串行瓶颈。

In those cases, use timday's examples with a parallel_foror alike.

在这些情况下,使用 timday 的示例和parallel_for类似的。

回答by Vazquinhos

1-

1-

 //!
 //! Get the default number of threads
 //!
 int nDefThreads = tbb::task_scheduler_init::default_num_threads();

 //!
 //! Init the task scheduler with the wanted number of threads
 //!
 tbb::task_scheduler_init init(nDefThreads);

2-

2-

Maybe if your code permits, the best way to run independent task with TBB is the parallel_invoke. In the blog of intel developers zone there is a post explaining some cases of how helpfull parallel_invoke could be. Check out this

也许如果您的代码允许,使用 TBB 运行独立任务的最佳方法是parallel_invoke。在 intel 开发人员专区的博客中,有一篇文章解释了 parallel_invoke 有多大帮助的一些案例。看看这个