0

配列から Max 値を取得する 2 つの異なる方法を見つけましたが、並列プログラミングはあまり好きではないので、よくわかりません。

このメソッドは同じことをするのだろうか、それとも何か足りないのでしょうか? 私は本当に彼らについて多くの情報を持っていません。コメントすらない…

最初の方法:

int[] vec = ... (I guess the content doesn't matter)

static int naiveMax()
{
    int max = vec[0];
    object obj = new object();

    Parallel.For(0, vec.Length, i =>
    {
        lock (obj) {
                if (vec[i] > max) max = vec[i];
        }
    });

    return max;
}

そして2番目のもの:

static int Max()
{
    int max = vec[0];
    object obj = new object();

    Parallel.For(0, vec.Length,     //could be Parallel.For<int>
        () => vec[0],
        (i, loopState, partial) =>
    {
        if(vec[i]>partial) partial = vec[i];
        return partial;
    },
    partial => {
            lock (obj) {
                    if( partial > max) max = partial;
            }
    });
    return max;
}

これらは同じことをしますか、それとも何か違うことをしますか? ありがとう ;)

4

2 に答える 2

2

どちらも整数の配列で最大値を見つけます。最大値をより速く見つけようとして、Parallel.For Methodを使用して「並行して」実行します。ただし、どちらの方法もこれで失敗します。

これを確認するには、まず十分に大きな整数の配列が必要です。小さい配列の場合、並列処理によって速度が向上することはありません。

int[] values = new int[100000000];
Random random = new Random();
for (int i = 0; i < values.Length; i++)
{
    values[i] = random.Next();
}

これで、2 つのメソッドを実行して、所要時間を確認できます。適切なパフォーマンス測定セットアップ ( Stopwatch、100,000,000 個の整数の配列、100 回の反復、リリースビルド、デバッガーが接続されていない、JIT ウォームアップ) を使用すると、マシンで次の結果が得られます。

naiveMax   00:06:03.3737078
Max        00:00:15.2453303

そのため、 (6 分!Max) よりもはるかに優れています。naiveMax

しかし、たとえばPLINQと比べてどうですか?

static int MaxPlinq(int[] values)
{
    return values.AsParallel().Max();
}
MaxPlinq   00:00:11.2335842

悪くありません。数秒節約できました。forでは、比較のために単純で古いシーケンシャルループはどうでしょうか。

static int Simple(int[] values)
{
    int result = values[0];
    for (int i = 0; i < values.Length; i++)
    {
        if (result < values[i]) result = values[i];
    }
    return result;
}
Simple     00:00:05.7837002

私たちには勝者がいると思います。

教訓: Parallel.Forは、魔法のようにコードを高速化するためにコードに振りかける妖精の粉ではありません。パフォーマンスが重要な場合は、適切なツールを使用して測定、測定測定、...

于 2013-06-28T15:09:21.393 に答える
0

それらは同じことをしているように見えますが、非常に非効率的です。並列化のポイントは、独立して実行できるコードの速度を向上させることです。競合状態のため、(ここで実装されているように) 最大値を検出するには、実際のロジックでアトミック セマフォ/ロックが必要です...つまり、とにかくコードを順番に実行するために、多くのスレッドと関連リソースをスピンアップしていることを意味します...完全に並列化の目的。

于 2013-06-28T15:10:10.847 に答える