TBB的學習

 

 

1. TBB簡介

TBB ( Thread Building Blocks, 線程構建模塊) 是Intel公司開發的並行編程開發的工具。它支持Windows,OS X, Linux平臺,支持的編譯器有Visual C++ (version 8.0 or higher, on Windows only), Intel C++ Compiler (version 11.1 or higher) or the GNU Compiler Collection (gcc).ios

TBB is a collection of components for parallel programming:算法

  • Basic algorithms: parallel_for, parallel_reduce, parallel_scan
  • Advanced algorithms: parallel_while, parallel_do, parallel_pipeline, parallel_sort
  • Containers: concurrent_queue, concurrent_priority_queue, concurrent_vector, concurrent_hash_map
  • Scalable memory allocation: scalable_malloc, scalable_free, scalable_realloc, scalable_calloc, scalable_allocator, cache_aligned_allocator
  • Mutual exclusion: mutex, spin_mutex, queuing_mutex, spin_rw_mutex, queuing_rw_mutex, recursive_mutex
  • Atomic operations: fetch_and_add, fetch_and_increment, fetch_and_decrement, compare_and_swap, fetch_and_store
  • Timing: portable fine grained global time stamp
  • Task Scheduler: direct access to control the creation and activation of tasks

2. 應用場景

  1. 數據包處理: 如 network router emulator
  2. 圖像處理,和OPENCV,IPP一塊使用,如 IPP with TBB
  3. 任何可並行的地方

3. 配置

1. 下載地址:https://www.threadingbuildingblocks.org/download編程

下載:windows release版tbb43_20150424oss_win.zip - 配置環境變量PATH,保證運行時找到dll - 在TBB應用工程中添加tbb包含目錄,即tbb相關頭文件 - 在TBB應用工程中添加tbb庫目錄,即tbb的lib文件,注意32位和64位有分別的目錄

4. 實例

問題:查找一個範圍內的全部素數,子問題是判斷一個數是否是素數,並且每一個數字的判斷互不影響,因此能夠用並行算法vim

  find_prime.ccwindows

/*
    ** find_prime.cc
    ** g++ find_prime.cc -ltbb -lrt -o find_prime
    ** -ltbb for tbb library
    ** -lrt for tbb::tick_count::now() using clock_gettime()
    */
    #include<iostream>
    #include<tbb/tbb.h>
    using namespace std;
    using namespace tbb;
    int is_prime(int x)
    {
        int i;
        if (x <= 1) {       /*1不是質數,且不考慮負整數與0,故輸入x<=1時輸出為假 */
            return 0;
        }
        for (i = 2; i * i <= x; ++i) {
            if (x % i == 0) {   /*若整除時輸出為假,否則輸出為真 */
                return 0;
            }
        }
        return 1;
    }
    class FindPrime {
     public:
        void operator() (const blocked_range < size_t > &r)const {
            for (size_t i = r.begin(); i != r.end(); ++i) {
                if (is_prime(i)) {
                    cout << i << endl;
                }
            }
        }
    };
    int main(int argc, char *argv[])
    {
        size_t end = 100;
        if (argc > 1 && atoi(argv[1]) > 0) {
            end = atoi(argv[1]);
        }
        parallel_for(blocked_range < size_t > (0, end), FindPrime());
        return 0;
    }

編譯markdown

g++ find_prime.cc -ltbb -lrt -o find_prime 

5. C++相關特性

0. operator overloading

parallel_for第二參數是一個類A的實例對象,該類A要重載操做符 () .app

對於less

class Test{ public: void operator()(const int &i) const{ cout<<"operation with i" <<endl; } }; 第一個const保證i不被改變,第二個const保證調用對象不被改變。 使用方法 Test t; t(110); 

1. lambda表達式

匿名函數在C++11中引用,語法是函數

[capture子句](參數列表)mutable throw() -> int{函數體} 

最簡單的一個例子,沒有參數,沒有異常處理,沒有返回類型(自動推斷)工具

[]{cout<<"hello world from lambda!"<<endl;}(); 

最後的 () 是對匿名函數的調用,分開來看是這樣的,首先定義一個函數指針

typedef void (*func)(); func f = []{cout<<"hello world from lambda!"<<endl;}; f(); 

capture子句主要有兩個符號 = , &= 表示以傳值的方式傳遞參數, & 表示以引用的方式(傳地址)傳遞參數,這兩個符號能夠單獨使用,也能夠組合使用, & 後面還能夠跟一個變量,只修飾它。

[] // 沒有定義任何變數。使用未定義變數會致使錯誤。 [x, &y] // x以傳值方式傳入(預設),y以傳地址方式傳入。 [&] // 任何被使用到的外部變數皆隱式地以地址方式加以引用。 [=] // 任何被使用到的外部變數皆隱式地以傳值方式加以引用。 [&, x] // x顯示地以傳值方式加以引用。其餘變數以地址方式加以引用。 [=, &z] // z顯示地以地址方式加以引用。其餘變數以傳值方式加以引用。 

2. placement new

所謂placement new就是在用戶指定的內存位置上構建新的對象,這個構建過程不須要額外分配內存,只須要調用對象的構造函數便可。

Task Scheduler 庫會用到這一特性

#include <iostream> #include "tbb/tbb.h" using namespace tbb; using namespace std; class first_task:public task { public: task * execute() { cout << "Hello World!\n"; return NULL; } }; int main() { task_scheduler_init init(task_scheduler_init::automatic); first_task & f1 = *new(tbb::task::allocate_root())first_task(); tbb::task::spawn_root_and_wait(f1); return 0; } 

endl;

參考博客:http://www.tuicool.com/articles/R3uu22

相關文章
相關標籤/搜索