マルチコアと同期
配列の全要素の合計を複数のスレッドで求めるとき、性能のために適した方法はどれか。
- Aすべてのスレッドが、要素ごとに1つの共有の変数へロックを取って足す
- Bすべてのスレッドが、要素ごとに1つの共有の変数へ同期なしで足す
- C各スレッドが自分の担当分を局所変数で合計し、最後にそれらを1回ずつ足し合わせる
答えと解説を見る
正解:C. 各スレッドが自分の担当分を局所変数で合計し、最後にそれらを1回ずつ足し合わせる
要素ごとに共有の変数を更新すると、ロックやアトミック命令の待ちと、キャッシュラインの行き来で非常に遅くなります。各スレッドがレジスタや局所変数で部分和を求め、最後にスレッドの数だけの足し算で全体の和を出せば、共有の書き込みはごくわずかです。この方法をリダクションと呼び、OpenMPなどの並列化の仕組みにも組み込まれています。
- A. ロックの待ちと通信で、並列化の効果がほとんどなくなります。
- B. データ競合で、合計が正しくなりません。
- C. 正しい。リダクションと呼ばれる方法です。