5

FIFO(スレッドセーフなもの)にアイテムが追加されているとしましょう(方法は気にしません)

|__|  |
|  |  |
|__|  |
|  |  |
|__|  V
| d|
|__|
| c|
|__|
| b|
|__|
| a|

ここで、アイテムを (1 つずつ) 別の並行コレクションに挿入する必要があるとしましょう。

データ挿入の速度は動的です。

最速でやりたい。(すべての要素を から に転送しますFifo) collection

しかし、私は競合しています:

  • 1 つのスレッドを使用して からアイテムを引き出し、Fifoに挿入することができましたcollection。しかし、私は私を助けることができるコア/他のスレッドを使用しません。

  • 複数のコンシューマー スレッドを使用して から項目を取得できますFifoが、Fifo(読み取り時) の内部ロックとcollection(書き込み時) の内部ロックにより、最終的にパフォーマンスが低下する可能性があります。

つまり、大量のコンシューマ スレッドがある場合、fifo/コレクションによる膨大な内部ロックに加えて、多数のコンテキスト スイッチングが発生する状況が発生します。

この種の問題に正しい方法でアプローチするにはどうすればよいですか? ガイドラインは何ですか?

4

4 に答える 4

1

複数のスレッドが同じ並行コレクションをめぐって競合することは、常にボトルネックの状況になります。通常、この問題はスレッド数が多いほど悪化しますが、劣化の速度はロック メカニズムによって異なります。.NET 4.0 の新しい同時実行コレクションはロックフリーであるか、少なくとも非ブロッキング ロックを使用するため、ある程度競合に強いはずです。

質問は自由回答のように見えるので、さまざまな数のスレッドを試して、fifo の競合と達成したいスループットのバランスを見つけることをお勧めします。

于 2013-01-09T07:28:22.000 に答える
0

コレクション間で最小限の処理を行う場合は、1つのスレッドのみを使用してください。複数の宛先コレクションがある場合は、複数のスレッドを使用することをお勧めします。または、両端のデータ構造が高度なロックを備えた複雑な構造である場合は、ロックだけでなく、実際にはマルチスレッド挿入をサポートします。

于 2013-01-09T07:32:31.833 に答える
0

両方のコレクションの内部にアクセスできる場合、これはいくつかの非相互作用スレッドによって実行できます。たとえば、そのスタックが既知のサイズのリンクされたリストである場合、2 つのスレッドはそれを両端から処理し、一方の要素を末尾に追加し、もう一方の要素を先頭に追加して、新しいリンク リストを構築できます。

反対に、スタックも配列である場合、単一スレッドでの memcpy のアナログよりも高速になるものはおそらくありません。

于 2013-01-09T07:46:04.940 に答える
0

これには、Task Parallel Library (TPL) の使用を検討します。

キューを保持し、アイテムがある場合は、並列フレームワークにすべての面倒な作業を任せることができます。毛むくじゃらのコード管理スレッドで独自のスレッド プールを処理する必要はありません。

私はまだこれを自分で行っていないことを告白しなければなりませんが、私があなたの状況にあった場合、TPL スキルを更新し、スレッド x ではなくタスクの観点から考え始めるでしょう.

于 2013-01-09T07:36:43.100 に答える