Achieving Speedups with Small Parallel Loop Bodies より。
イテレーションが小さいときにうかつに Parallel にするとかえってパフォーマンスが悪くなる可能性があります。
例としてこんなコードが載っています。
int[] array = new int[100000000]; Parallel.For(0, array.Length, i => { array[i] = i * i * i; });
これだと 「array[i] = i*i*i;」 というだけのコードをパラレルにものすごい回数実行するため、パラレルのオーバーヘッドがしゃれにならないくらい大きくなってしまうわけですね。
普通の for ループにしてしまえばパラレルにするオーバーヘッドは無くなりますが、それではスレッド一つしか使わないためもったいないです。
上記の記事では、こういった場合に使える ForRange というちょっとしたメソッドが紹介されています。
ForRange はこんな風に使います。
int[] array = new int[100000000]; ForRange(0, array.Length, (from, to) => { for (int i = from; i < to; ++i) { array[i] = i * i * i; } });
上記記事に載っているソースコードを見れば明らかですが、ForRange は Environment.ProcessorCount (搭載されているプロセッサ・コア数) 分に分割して Parallel.For を呼ぶようになっています。
仮にプロセッサ・コア数が 4 つの場合は、上記のコードは 0~25000000、25000000~50000000、50000000~75000000、75000000~100000000 の 4 の for ループが Parallel.For されることになります。
なるほどなぁ。
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。