1

次のコード:

#include <ppl.h>
int i;
vector<int> val(10),summ(10,0);
for(i=0;i<10;i++) val[i]=i;

parallel_for(0, 10, [&] (int y){
    vector<int> vett(1000);
    double vall=val[y];

    for(i=0;i<vett.size();i++)
        vett[i]=vall;

    for(i=0;i<vett.size();i++)
        summ[y]+=vett[i];
 });

for(i=0;i<10;i++)
cout<<summ[i]<<endl;

次のようなランダムな出力を生成します: 0 1000 1468 204 3600 25 5898 7000 7456 1395

「結合可能」を使用する必要があると思いますが、それについて見つけたドキュメントはあまり良くありません。このコードを正しく動作させる方法を知っていますか? vett が 2 次元ベクトルの場合はどうなりますか?

並列コンピューティングを学びたいので、この新しい Microsoft ライブラリを学ぶ価値はありますか、それともより良い代替手段がありますか?

4

2 に答える 2

2

コードの主な問題は、i添字変数です。同時に複数の並列タスクで使用されています。混沌が続き、不安定な結果の理由です。最も簡単な修正は、次のようにラムダでループを宣言することです。

for(int i=0;i<vett.size();i++)
    vett[i]=vall;

for(int i=0;i<vett.size();i++)
    summ[y]+=vett[i];

各ループ インデックスは、forループの初期化で宣言されることに注意してください。iこれはより慣用的な使用法であり、ループが終了した後の最終値が本当に必要でない限り、すべてのループで使用できます。

于 2012-02-14T14:18:00.243 に答える
1

並列コードの優れた経験則は、共有変数の数を最小限に抑えることです。

結果として、(または)[&]のラムダ キャプチャとして使用しないでください。共有する必要がある変数のみをキャプチャします。parallel_forstd::thread

これを行うと、@Blastfurnace が指摘した問題、つまりiすべてのワーカー間で共有されていた問題を発見したことになります。

于 2012-02-14T15:23:41.033 に答える