2012-05-15 19 views
17

किसी ने मुझे एक TBB उदाहरण कैसे दे सकते हैं:सरल TBB उदाहरण

  1. सक्रिय धागे की अधिकतम संख्या को निर्धारित किया है।
  2. कार्यों को निष्पादित करें जो एक-दूसरे से स्वतंत्र हैं और वर्ग के रूप में प्रस्तुत किए गए हैं, स्थिर कार्य नहीं।

उत्तर

26

यहां कुछ पूर्ण उदाहरण हैं, parallel_for का उपयोग करते हुए, दूसरा parallel_for_each का उपयोग कर रहा है।

अपडेट 2014-04-12: ये दिखाएं कि मैं अब टीबीबी का उपयोग करने का एक सुंदर पुराना तरीका मानता हूं; मैंने parallel_for का उपयोग कर C12+ 11 लैम्ब्डा के साथ separate answer जोड़ा है।

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

दोनों एक Debian/खरखरा (छ ++ 4.7) g++ tbb_example.cpp -ltbb साथ सिस्टम पर संकलन (तब ./a.out के साथ चलाने)

(this question देखें के साथ कि "invoker" बात की जगह के लिए एक std::mem_fun_ref या boost::bind)।

15

यहां लैम्ब्डा के साथ parallel_for का अधिक आधुनिक उपयोग है; संकलित करता है तथा 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-

हो सकता है कि अपने कोड परमिट अगर, TBB साथ स्वतंत्र कार्य चलाने के लिए सबसे अच्छा तरीका है parallel_invoke है । इंटेल डेवलपर्स जोन के ब्लॉग में एक पोस्ट है जो कुछ मामलों को समझाता है कि समानांतर_इनवोक कितना सहायक हो सकता है। this

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 के उदाहरणों का उपयोग करें।

संबंधित मुद्दे