小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

c++并行計(jì)算庫(kù)TBB和PPL的基本用法

 kingwenguang 2014-11-11

并行庫(kù)充分利用多核的優(yōu)勢(shì),通過并行運(yùn)算提高程序效率,本文主要介紹c++中兩個(gè)知名的并行庫(kù),一個(gè)是intel開發(fā)的TBB,一個(gè)是微軟開發(fā)的PPL。本文只介紹其基本的常用用法:并行算法和任務(wù)。

TBB(Intel? Threading Building Blocks )
TBB是intel用標(biāo)準(zhǔn)c++寫的一個(gè)開源的并行計(jì)算庫(kù)。它的目的是提升數(shù)據(jù)并行計(jì)算的能力,可以在他的官網(wǎng)上下載最新的庫(kù)和文檔。TBB主要功能:
并行算法
任務(wù)調(diào)度
并行容器
同步原語(yǔ)
內(nèi)存分配器
TBB并行算法
parallel_for:并行方式遍歷一個(gè)區(qū)間。
parallel_for(1, 20000, [](int i){cout << i << endl; });
parallel_for(blocked_range(0, 20000), [](blocked_range& r)
{
    for (size_t i = r.begin(); i != r.end(); ++i)
        cout << i << endl; 
});
parallel_do和parallel_for_each:將算法應(yīng)用于一個(gè)區(qū)間
vector v;
parallel_do(v.begin(), v.end(), [](size_t i){cout << i << endl; });
parallel_for_each(v.begin(), v.end(), [](size_t i){cout << i << endl; });
 parallel_reduce
  類似于map_reduce,但是有區(qū)別。它先將區(qū)間自動(dòng)分組,對(duì)每個(gè)分組進(jìn)行聚合(accumulate)計(jì)算,每組得到一個(gè)結(jié)果,最后將各組的結(jié)果進(jìn)行匯聚(reduce)。這個(gè)算法稍微復(fù)雜一點(diǎn),parallel_reduce(range,identity,func,reduction),第一個(gè)參數(shù)是區(qū)間范圍,第二個(gè)參數(shù)是計(jì)算的初始值,第三個(gè)參數(shù)是聚合函數(shù),第四個(gè)參數(shù)是匯聚參數(shù)。
復(fù)制代碼
float ParallelSum(float array [], size_t n) {
    return parallel_reduce(
        blocked_range(array, array + n),
        0.f,
        [](const blocked_range& r, float value)->float {
            return std::accumulate(r.begin(), r.end(), value);
    },
        std::plus()
        );
}
復(fù)制代碼
這個(gè)對(duì)數(shù)組求和的例子就是先自動(dòng)分組然后對(duì)各組中的元素進(jìn)行聚合累加,最后將各組結(jié)果匯聚相加。
parallel_pipeline:并行的管道過濾器
  數(shù)據(jù)流經(jīng)過一個(gè)管道,在數(shù)據(jù)流動(dòng)的過程中依次要經(jīng)過一些過濾器的處理,其中有些過濾器可能會(huì)并行處理數(shù)據(jù),這時(shí)就可以用到并行的管道過濾器。舉一個(gè)例子,比如我要讀入一個(gè)文件,先將文件中的數(shù)字提取出來,再將提取出來的數(shù)字做一個(gè)轉(zhuǎn)換,最后將轉(zhuǎn)換后的數(shù)字輸出到另外一個(gè)文件中。其中讀文件和輸出文件不能并興去做,但是中間數(shù)字轉(zhuǎn)換的環(huán)節(jié)可以并行去做的。parallel_pipeline的原型:
parallel_pipeline( max_number_of_live_tokens, 
                   make_filter(mode0,g0) &
                   make_filter(mode1,g1) &
                   make_filter(mode2,g2) &
                   ... 
                   make_filter(moden,gn) );
  第一個(gè)參數(shù)是最大的并行數(shù),我們可以通過&連接多個(gè)filter,這些filter是順序執(zhí)行的,前一個(gè)filter的輸出是下一個(gè)filter的輸入。
復(fù)制代碼
float RootMeanSquare( float* first, float* last ) {
    float sum=0;
    parallel_pipeline( /*max_number_of_live_token=*/16,       
        make_filter(
            filter::serial,
            [&](flow_control& fc)-> float*{
                if( first
                    return first++;
                 } else {
                    fc.stop();
                    return NULL;
                }
            }    
        ) &
        make_filter(
            filter::parallel,
            [](float* p){return (*p)*(*p);} 
        ) &
        make_filter(
            filter::serial,
            [&](float x) {sum+=x;}
        )
    );
    return sqrt(sum);
}
復(fù)制代碼
  第一個(gè)filter生成數(shù)據(jù)(如從文件中讀取數(shù)據(jù)等),第二個(gè)filter對(duì)產(chǎn)生的數(shù)據(jù)進(jìn)行轉(zhuǎn)換,第三個(gè)filter是對(duì)轉(zhuǎn)換后的數(shù)據(jù)做累加。其中第二個(gè)filter是可以并行處理的,通過filter::parallel來指定其處理模式。
parallel_sort:并行排序
const int N = 1000000;
float a[N];
float b[N];
parallel_sort(a, a + N);
parallel_sort(b, b + N, std::greater());
parallel_invoke:并行調(diào)用,并行調(diào)用多個(gè)函數(shù)
void f();
extern void bar(int);
void RunFunctionsInParallel() {
    tbb::parallel_invoke(f, []{bar(2);}, []{bar(3);} );
}
TBB任務(wù)
task_group表示可以等待或者取消的任務(wù)集合
task_group g;
g.run([]{TestPrint(); });
g.run([]{TestPrint(); });
g.run([]{TestPrint(); });
g.wait();
PPL(Parallel Patterns Library)
  PPL是微軟開發(fā)的并行計(jì)算庫(kù),它的功能和TBB是差不多的,但是PPL只能在windows上使用。二者在并行算法的使用上基本上是一樣的, 但還是有差異的。二者的差異:
parallel_reduce的原型有些不同,PPL的paraller_reduce函數(shù)多一個(gè)參數(shù),原型為parallel_reduce(begin,end,identity,func,reduction), 比tbb多了一個(gè)參數(shù),但是表達(dá)的意思差不多,一個(gè)是區(qū)間,一個(gè)是區(qū)間迭代器。
PPL中沒有parallel_pipeline接口。
TBB的task沒有PPL的task強(qiáng)大,PPL的task可以鏈?zhǔn)竭B續(xù)執(zhí)行還可以組合任務(wù),TBB的task則不行。
PPL任務(wù)的鏈?zhǔn)竭B續(xù)執(zhí)行then
復(fù)制代碼
int main()
{
    auto t = create_task([]() -> int
    { 
        return 0;
    });
    // Create a lambda that increments its input value.
    auto increment = [](int n) { return n + 1; };
    // Run a chain of continuations and print the result. 
    int result = t.then(increment).then(increment).then(increment).get();
    cout << result << endl;
}
/* Output:
    3
*/
復(fù)制代碼
PPL任務(wù)的組合
  1.when_all可以執(zhí)行一組任務(wù),所有任務(wù)完成之后將所有任務(wù)的結(jié)果返回到一個(gè)集合中。要求該組任務(wù)中的所有任務(wù)的返回值類型都相同。
復(fù)制代碼
array, 3> tasks =
{
    create_task([]() -> int { return 88; }),
    create_task([]() -> int { return 42; }),
    create_task([]() -> int { return 99; })
};
auto joinTask = when_all(begin(tasks), end(tasks)).then([](vector results)
{
    cout << "The sum is " 
          << accumulate(begin(results), end(results), 0)
          << '.' << endl;
});
// Print a message from the joining thread.
cout << "Hello from the joining thread." << endl;
// Wait for the tasks to finish.
joinTask.wait();
復(fù)制代碼
2.when_any任務(wù)組中的某一個(gè)任務(wù)執(zhí)行完成之后,返回一個(gè)pair,鍵值對(duì)是結(jié)果和任務(wù)序號(hào)。
復(fù)制代碼
array, 3> tasks = {
        create_task([]() -> int { return 88; }),
        create_task([]() -> int { return 42; }),
        create_task([]() -> int { return 99; })
    };
    // Select the first to finish.
    when_any(begin(tasks), end(tasks)).then([](pair result)
    {
        cout << "First task to finish returns "
              << result.first
              << " and has index "
              << result.second<
    }).wait();
//output: First task to finish returns 42 and has index 1.
復(fù)制代碼
總結(jié):
  ppl和tbb兩個(gè)并行運(yùn)算庫(kù)功能相似,如果需要跨平臺(tái)則選擇tbb,  否則選擇ppl。ppl在任務(wù)調(diào)度上比tbb強(qiáng)大,tbb由于設(shè)計(jì)上的原因不能做到任務(wù)的連續(xù)執(zhí)行以及任務(wù)的組合,但是tbb有跨平臺(tái)的優(yōu)勢(shì)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多