1

scala で並列マップを使用する大規模なバッチ並列計算があります。ワーカーが終了するにつれて、CPU 使用率が徐々に低下しているように見えることに気付きました。それはすべて Map オブジェクト内の呼び出しへの呼び出しに帰着します

scala.collection.parallel.thresholdFromSize(length, tasksupport.parallelismLevel)

コードを見ると、次のようになります。

def thresholdFromSize(sz: Int, parallelismLevel: Int) = {
  val p = parallelismLevel
  if (p > 1) 1 + sz / (8 * p)
  else sz
}

私の計算は多数のコアでうまく機能し、その理由がわかりました..

thesholdFromSize(1000000,24) = 5209
thesholdFromSize(1000000,4) = 31251

24 個の CPU で長さ 1000000 の配列がある場合、5209 要素まで分割されます。同じ配列を 4 CPU マシンの並列コレクションに渡すと、31251 要素でパーティショニングが停止します。

私の計算の実行時間は均一ではないことに注意してください。ユニットあたりの実行時間は最大 0.1 秒です。31251 アイテムで、それは 3100 秒、つまり 52 分の時間で、他のワーカーが介入して仕事をつかむことができますが、そうではありません。並列計算中に CPU 使用率を監視しているときに、まさにこの動作を観察しました。明らかに、大きなマシンで実行したいのですが、それが常に可能であるとは限りません。

私の質問はこれです:並列コレクションに影響を与えて、私の問題により適したより小さなしきい値を与える方法はありますか? 私が考えることができる唯一のことは、クラス 'Map' の独自の実装を作成することですが、それは非常に洗練されていない解決策のようです。

4

3 に答える 3

0

0.1 秒は、それを個別に処理するのに十分な時間です。各ユニット (または 10 ユニット) の処理を​​個別の Runnable にラップし、それらすべてを FixedThreadPool に送信します。もう 1 つのアプローチは、ForkJoinPool を使用することです。これにより、すべての計算の終了を簡単に制御できます。

于 2013-10-10T20:39:39.670 に答える