8

最近、PLINQ を使用してデータ処理を実行しています。

基本的に、私は約 4000 の時系列 (基本的に のインスタンスDictionary<DataTime,T>) を持っており、それらを というリストにストックしていますtimeSeries

操作を実行するには、次のようにします。

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

さまざまなコアで何が起こっているかを見ると、最初に、すべての CPU が使用されており、コンソール (いくつかのログを出力する場所) で複数の時系列が同時に処理されていることがわかります。

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

少し考えてみたところ、リストの最初と最後に の観点timeSeriesから処理しやすいインスタンスが含まれていることに気付きました。myOperationそれで、PLINQ が使用していたアルゴリズムは、たとえば 4 つのコアに 4000 のインスタンスを分割して、それぞれに 1000 を与えることで構成されているのではないかと思いました。その後、コアが作業の割り当てを完了すると、アイドル状態に戻ります。これは、コアの 1 つがはるかに重いワークロードに直面している可能性があることを意味します。

私の理論は正しいですか、それとも別の可能な説明がありますか?

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

4

1 に答える 1

5

これに対抗する必要がある「ワークスティーリング」と呼ばれるものがありますが、あなたの理論はおそらく正しいでしょう。なぜここでうまくいかないのかわかりません。外側の端に多数 (>= 数十) の大きなジョブがありますか、それともほんの数個ですか?

データをシャッフルする以外に、カスタム Partionerを受け入れるオーバーロードを使用できます。そうすることで、よりバランスの取れた仕事ができるようになります。AsParallel()

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

于 2013-07-25T08:15:59.217 に答える