Ai đó có thể cho tôi một ví dụ TBB cách:đơn giản TBB dụ
- thiết lập số lượng tối đa của chủ đề hoạt động.
- thực thi các tác vụ độc lập với nhau và được trình bày dưới dạng lớp, chứ không phải các chức năng tĩnh.
Ai đó có thể cho tôi một ví dụ TBB cách:đơn giản TBB dụ
Dưới đây là một vài ví dụ hoàn chỉnh, một ví dụ sử dụng parallel_for
, cái còn lại sử dụng parallel_for_each
.
Cập nhật 2014-04-12: Đây là những gì tôi cho là một cách khá cũ thời sử dụng TBB ngay bây giờ; Tôi đã thêm separate answer bằng cách sử dụng parallel_for
với lambda C++ 11.
#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;
}
và
#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;
}
Cả hai biên dịch trên Debian/Wheezy (g ++ 4.7) hệ thống với g++ tbb_example.cpp -ltbb
(sau đó chạy với ./a.out
)
(Xem this question để thay thế mà "invoker
" điều với a std::mem_fun_ref
hoặc boost::bind
).
Đây là cách sử dụng hiện đại hơn parallel_for
với một lambda; biên dịch và chạy trên Debian/Wheezy với 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;
}
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-
Có lẽ nếu giấy phép mã của bạn, cách tốt nhất để chạy nhiệm vụ độc lập với TBB là parallel_invoke . Trong blog của các nhà phát triển intel khu vực có một bài giải thích một số trường hợp như thế nào hữu ích parallel_invoke có thể được. Hãy xem this
Nếu bạn chỉ muốn chạy một vài tác vụ đồng thời, việc sử dụng tbb::task_group
có thể dễ dàng hơn. Ví dụ lấy từ 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;
}
}
Lưu ý tuy nhiên đó
Tạo một số lượng lớn các nhiệm vụ cho một task_group duy nhất là không thể mở rộng, vì tạo ra nhiệm vụ trở thành một nút cổ chai nối tiếp.
Trong những trường hợp đó, hãy sử dụng các ví dụ về ngày giờ có số parallel_for
hoặc giống nhau.