1

本質的にシーケンシャルである単一のMCMCチェーンを並列化しようとしているため、実行される反復の順序を維持する必要があります。この目的のために、私はOpenMPを介して「orderedfor」ループを使用することを考えていました。OpenMPでの順序付きforループの実行が実際にどのように機能するのか知りたいのですが、コードの並列化に関して実際にスピードアップを提供しますか?

ありがとう!

4

3 に答える 3

2

ループに順序付けられた構造を持つブロックが1つしかない場合、実行はシリアルになり、並列実行によるスピードアップは得られません。以下の例では、並列で実行できる1つのブロックと、シリアル化される1つのブロックがあります。

void example(int b, int e, float* data) 
{
    #pragma omp for schedule(static) ordered
    for (int i = b; i < e; ++i) {
        // This block can be executed in parallel
        data[i] = SomeThing(data[i]);
        if (data[i] == 0.0f) 
        {
            // This block will be serialized 
            #pragma omp ordered
            printf("Element %d resulted in zero\n", i);
        }
    }
}
于 2012-01-25T09:10:23.590 に答える
1

マルコフ連鎖が1つしかない限り、それを並列化する最も簡単な方法は、「恥ずかしい」並列処理を使用することです。多数の独立した連鎖を実行し、すべてが完了したら結果を収集します[またはしばらく。]

このようにして、通信のオーバーヘッドは一切発生しません。

ここでの主な注意点は、異なるチェーンが異なる乱数ジェネレータシードを取得することを確認する必要があるということです。

UPD:結果を収集する実用性。

一言で言えば、すべてのチェーンによって生成された結果を混ぜ合わせるだけです。簡単にするために、3つの独立したチェーンがあるとします。

x1, x2, x3,...
y1, y2, y3,...
z1, z2, z3,...

これらから、チェーンを作成します。x1,y1,z1,x2,y2,z2,x3,y3,z3,...これは完全に有効なMCチェーンであり、正しい分布をサンプリングします。

すべてのチェーン履歴を書き出すことは、ほとんどの場合非現実的です。通常、各チェーンはビニング統計を保存します。その後、これらの統計を混合して、個別のプログラムで分析します。ビニング分析については、たとえば[boulder.research.yale.edu/Boulder-2010/ReadingMaterial-2010/Troyer/Article.pdf][1]を参照してください。

于 2012-01-25T13:35:03.527 に答える
0

openMPの順序付きディレクティブは、動的な観点でのみリストできます。
仕様は、私たちが書く間、順序付けられたキーワードに言及しなければならないことを示唆しています。ただし、ループ内のどこに順序付けられたブロックがあるかを選択します。

私の推測では、forでorderedキーワードについて言及したとしても、各スレッドは並行して作業を開始します。順序付けられたキーワードに遭遇したスレッドは、前のすべての反復が完了した場合にのみ、このブロックに入る必要があります。以前のすべての反復を完了する必要があるキーワードに焦点を合わせてください。

上記の推論の直感は、連続して実行された場合の「注文済み」はまったく意味がないということです。

于 2012-01-25T08:51:06.103 に答える