2012-05-15 21 views
17

誰かが私にTBB例を与えることができる方法に:最も簡単なTBBの例

  1. は、アクティブなスレッドの最大数を設定します。
  2. は、互いに独立したタスクを実行し、静的関数ではなくクラスの形で提示します。

答えて

26

parallel_forを使用し、parallel_for_eachを使用して1つの完全な例を示します。

更新2014-04-12:これらは、私が今TBBを使用するかなり古い方法と思われるものを示しています。私はseparate answerparallel_forに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; 
} 

両方g++ tbb_example.cpp -ltbbでのDebian/Wheezyに(G ++ 4.7)システム上でコンパイル(当時./a.outで実行)

(とその "invoker" ものを交換するためのthis questionを参照してください。 std::mem_fun_refまたはboost::bind)。

15

parallel_forにはラムダを使用しています。コンパイルとg++ -std=c++11 tbb_example.cpp -ltbb && ./a.outでのDebian/Wheezyに上で実行されます:

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

あなたのコードが許すならば多分、TBBで独立したタスクを実行するための最良の方法であるparallel_invoke 。 intel developersゾーンのブログには、parallel_invokeの有用性のいくつかのケースを説明する記事があります。チェックアウトthis

2

2つのタスクを同時に実行したい場合は、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; 
    } 
} 

注しかし

は単一task_groupのために多数のタスクを作成することは、スケーラブルではありません。

このような場合は、parallel_forなどのtimdayの例を使用してください。

関連する問題