2013-07-25 4 views
8

私はPLINQを使ってデータ処理を行っています。なぜ私のParallel.ForAll呼び出しは1つのスレッドを使用して終了するのですか?

基本的に私はtimeSeriesという名前のリストに在庫している約4000の時系列(基本的にDictionary<DataTime,T>)を持っています。私の操作を実行するには

、私は単純に実行します。

timeSeries.AsParallel().ForAll(x=>myOperation(x)) 

私は私の異なるコアで何が起こっているのかを見てみると、私は最初に、すべての私のCPUが使用されていることに気づくと、私が上で見ますコンソール(いくつかのログを出力します)では、複数の時系列が同時に処理されます。

しかし、プロセスは時間がかかり、約45分後には、ログにはスレッドが1つしかないことが明白に示されます。何故ですか?

timeSeriesには、myOperationの処理の簡単なインスタンスがリストの先頭と最後に含まれていることがわかりました。だから、もしPLINQが使っていたアルゴリズムが、4000個のインスタンスを4つのコアに分割し、それぞれに1000個を渡しているのかどうか疑問に思っていました。そして、コアがその作業の割り当てで終了すると、これは、コアの1つが非常に重い作業負荷に直面している可能性があることを意味します。

私の理論は正しいのでしょうか、別の考えられる説明がありますか?

実行前にリストをシャッフルするか、その問題を解決するために使用できる並列処理パラメータがありますか?

答えて

5

あなたの理論はおそらく正しいですが、これに対抗すべき「ワークステリング」と呼ばれるものがあります。私はなぜそれがここで動作しないのか分からない。外の端に数多くの(> =数十)大きな仕事がありますか?

データをシャッフルする以外に、custom Partionerを受け入れるAsParallel()の場合はthe overloadを使用できます。そうすれば、作業のバランスを取ることができます。

サイドノート:この状況では、私はParallel.ForEach()より多くのオプションとクリーンな構文を好むでしょう。

+1

私が知る限り、仕事の窃盗はPLINQの反復ではなく、仕事で働いています。タスクがコレクションからアイテムの束を取得して処理する場合、他のタスクはそれらを盗むことができません。 – svick

+1

また、カスタムパーティショナーはここでは必要ないかもしれません[フレームワークによって提供されるもの](http://msdn.microsoft.com/en-us/library/system.collections.concurrent.partitioner.create.aspx )十分かもしれません。 – svick

+0

@svick - あなたはおそらく正しいでしょうが、それはfor-loopを指していて、たくさんのタスクを作成していますか?扱いにくいですね。 –

関連する問題