第4章 パラレルの基本 パラレルの基本
この作品はAIを使って翻訳されている。ご意見、ご感想をお待ちしている:translation-feedback@oreilly.com
このの章では、並列プログラミングのパターンを取り上げる。並列プログラミングは、CPUに負荷のかかる作業を分割し、複数のスレッドに分割するために使われる。これらの並列処理レシピは、CPUに束縛される作業だけを考えている。もし並列実行したい非同期演算子(I/Oバウンド演算子など)がある場合は、第2章、特にレシピ2.4を参照のこと。
この章で取り上げる並列処理抽象化は、タスク並列ライブラリ(TPL)の一部である。TPLは.NETフレームワークに組み込まれている。
4.1 データの並列処理
問題
、データの集まりがあり、データの各要素に対して同じ演算を実行する必要がある。この演算子はCPUに拘束され、時間がかかるかもしれない。
解決策
Parallel 型には、この問題のために特別に設計されたForEach メソッドが含まれている。次の例では、行列の集合を受け取り、それらをすべて回転させる:
voidRotateMatrices(IEnumerable<Matrix>matrices,floatdegrees){Parallel.ForEach(matrices,matrix=>matrix.Rotate(degrees));}
無効な値に遭遇した場合など、ループを早めに止めたい状況もあるだろう。以下の例では各行列を反転させているが、無効な行列に遭遇した場合はループを中断する:
voidInvertMatrices(IEnumerable<Matrix>matrices){Parallel.ForEach(matrices,(matrix,state)=>{if(!matrix.IsInvertible)state.Stop();elsematrix.Invert();});}
こののコードは、ParallelLoopState.Stop を使ってループを停止し、ループ本体のさらなる呼び出しを防いでいる。これは並列ループであるため、現在の項目以降の項目に対する呼び出しも含め、ループ本体に対する他の呼び出しが既に実行されている可能性があることに留意されたい。このコード例では、3番目の行列が反転しない場合、ループは停止され、新しい行列は処理されないが、他の行列(4番目や5番目など)はすでに処理されている可能性がある。
より一般的な状況としては、、並列ループをキャンセルしたい場合がある。これはループの停止とは異なる。ループはループの内側から停止され、ループの外側からキャンセルされる。例を示すと、このコード例のように、キャンセルボタンはCancellationTokenSource 、並列ループをキャンセルすることができる:
voidRotateMatrices(IEnumerable<Matrix>matrices,floatdegrees,CancellationTokentoken){Parallel.ForEach(matrices,newParallelOptions{CancellationToken=token},matrix=>matrix.Rotate(degrees));}
注意しなければならないのは、各並列タスクは異なるスレッドで実行される可能性があるため、共有される状態は保護されなければならないということだ。以下の例では、各行列を反転し、反転できなかった行列の数をカウントしている: ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access