3

の例と混同しています

http://msdn.microsoft.com/en-us/library/dd997393.aspx

Parallel.ForEach<int, long>(nums, // source collection
                                    () => 0, // method to initialize the local variable
                                    (j, loop, subtotal) => 
                                    {
                                        subtotal += nums[j]; 
                                        return subtotal; 
                                    },

                                    (finalResult) => Interlocked.Add(ref total,finalResult)                                        );

最後のデリゲート(finalResult) => Interlocked.Add(ref total,finalResult) がインターロックを必要とする理由がわかりませんが、前の式は

(j, loop, subtotal) => 
                                    {
                                        subtotal += nums[j]; 
                                        return subtotal; 
                                    },

ではない?

ありがとう

4

2 に答える 2

4

Parallel.For()およびメソッドはParallel.ForEach()パーティショナーを利用します。10,000 個の個別のタスクで 10,000 個の要素をループするのは非常に非効率的です。パーティショナーはデータをセグメントに分割し、理想的にForEach()は 4 コア CPU で 2,500 要素の 4 つのタスク (スレッド) で実行します。これにはヒューリスティックが必要な場合があり、独自のカスタム パーティショナーを作成できます。

「通常の」(単純な) オーバーロードを使用する場合、ForEach()これは完全に透過的です。ただし、この例では<TLocal>、パーティショニングを表面化するオーバーロードの 1 つを使用しています。

ステートメントは 1 つのsubtotal += nums[j];パーティション内で繰り返されるため、スレッドセーフです。

(finalResult) => Interlocked.Add(ref total,finalResult)パーティションがマージされる場所です。もちろん、この部分はスレッドセーフではありません。

于 2011-11-13T09:03:54.467 に答える
2

変数subtotalは、1 つのスレッドのみがアクセスできる「ローカル データ」です。

一方、totalはすべてのスレッドが変更できる変数であり、複数のスレッドが同時に合計を更新しようとする可能性があります。

于 2011-11-13T07:55:02.997 に答える