2013-06-17 17 views
6

私は5つのタスク( "A"、 "B"、 "C"、 "D"、 "E")を持っていますが、並列化したいのですがその依存関係に関して彼らは、このような順序で実行する必要があります。以前のすべてのものが完成し、「B」はAの後に実行する必要があり、ここに私の質問のときC++の連鎖

A --> B --\ 
C ----------> E 
D --------/ 

だから、「E」が実行されます。解決策(STL、ブースト)に行く準備ができていますか?あるいは、私はそれをstd :: threadに基づいて実装する必要がありますか?

+0

ハングオン - 私は以前これをどこかで見ましたか? –

+7

[N3558](http://open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3558.pdf)が承認されれば、これは 'auto flow = std :: when_all (std :: async(E)); '(std :: async(D))を実行します。 – Xeo

+0

@Xeoとてもいいです! Boost 1.54.0(現在はベータ版)のBoost.Threadでほとんど同じことができますが、自分でwhen_allを実装する必要があります。それは.then()を提供します(不完全ですが、エグゼキュータを変更する必要がない場合は動作するはずです)。 – Klaim

答えて

11

チェックアウトTBB's Flow GraphまたはPPLです。

TBBリンクの例では、おおよそスケッチしたものが表示されます。あなたはすでにタスクとして抽象化された問題を策定しました。最初はスレッドレベルに落ちる必要はありません。

1

私は一度も使ったことのないstd :: threadを使うことができますが、かなり簡単です。

はここcppreference.comで見つかった簡単なプログラムの例です:

#include <iostream> 
#include <thread> 
#include <chrono> 

void foo() 
{ 
    // simulate expensive operation 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
} 

void bar() 
{ 
    // simulate expensive operation 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
} 

int main() 
{ 
    std::cout << "starting first helper...\n"; 
    std::thread helper1(foo); 

    std::cout << "starting second helper...\n"; 
    std::thread helper2(bar); 

    std::cout << "waiting for helpers to finish...\n"; 
    helper1.join(); 
    helper2.join(); 

    std::cout << "done!\n"; 
} 

あなたは、スレッドが終了するのを待つために参加する()関数を使用することができます。 たとえば、タスクAを実行する新しいスレッドを作成します。その後、タスクBを実行する新しいスレッドを作成する前に終了します。

g ++ -std = C++ 0x- pthread main.cpp

また、いくつかの可能性を提供できるMPIとOpenMPを検索することもできます。

2

私はICMP、GCC、MSVCでできるOpenMP section指示文でこれを行うことができると思います。 OpenMP taskディレクティブはおそらくより良い選択であり、ICCとGCCで実行できますが、MSVCのどのバージョンでも実行できません。

以下のコードはOpenMP sectionsを使用しています。他のすべてのタスクが完了した後でEが実行されるので、それを並列化することも可能です。Eは、A, B, C, Dが終了した後にすべてのスレッドで実行されます。 Eがループを反復処理している場合、この方法でループを並列化できます。私はそれがあなたが望んでいるかどうかはわかりませんが、望むかのように1つのスレッドで実行するのは簡単です。

#include <stdio.h> 
#include <omp.h> 

void A() { printf("A\n"); } 
void B() { printf("B\n"); } 
void C() { printf("C\n"); } 
void D() { printf("D\n"); } 
void E() { 
    printf("E: %d\n", omp_get_thread_num()); 
    #pragma omp for 
    for(int i=0; i<10; i++) { 
    //do something as a function of i 
    } 
} 

void foo() { 
#pragma omp parallel // starts a new team 
{ 
    #pragma omp sections // divides the team into sections 
    { 
    { A(); B(); } 
    #pragma omp section 
    { C(); } 
    #pragma omp section 
    { D(); } 
    } 
    E(); 
} 
} 

int main() { 
    foo(); 
}