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
Simplest TBB example
提问by Jofsey
回答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_for
with 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_ref
or boost::bind
).
(请参阅此问题以将“ invoker
” 事物替换为std::mem_fun_ref
或boost::bind
)。
回答by timday
Here's a more modern use of parallel_for
with 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_for
or 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 有多大帮助的一些案例。看看这个