2012-05-15 47 views
17

Ai đó có thể cho tôi một ví dụ TBB cách:đơn giản TBB dụ

  1. thiết lập số lượng tối đa của chủ đề hoạt động.
  2. 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.

Trả lời

26

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

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

15

Đâ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

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

2

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.

Các vấn đề liên quan