8


1

私は.NET 3.5コンソールアプリケーションで厄介な並列化作業を行っています。ハイパースレッドプロセッサとマルチコアプロセッサを利用したいと思います。 *任意のシステムでこれらのどちらかを最適に利用するために、どのようにして最適な数のワーカースレッドを選択するのですか?*たとえば、デュアルコアの場合、2つのスレッドが必要です。クアッドコア私は4つのスレッドが欲しいでしょう。 最終的には、プロセッサの特性を決定して、作成するスレッド数を知ることができます。

どのように作業を分割するのか、あるいはどのようにスレッド化するのかを尋ねるのではなく、このコンソールアプリケーションが動作する任意のマシン上のスレッドの「最適な」数をどのように決定するのかを尋ねる。

13 Answer


15


自分で判断しようとしないことをお勧めします。 ThreadPoolを使用して、.NETにスレッドを管理させます。


9


それがあなたが後にしている唯一のものであるなら、あなたは Environment.ProcessorCountを使うことができます。 しかし、通常ThreadPoolを使用することは確かに良い選択肢です。


4


正しい数は明らかに http://en.wikipedia.org/wiki/Answer_to_Life,the_Universe,_and_Everything#Answer_to_Life.2C_the_Universe.2C_and_Everything.2842.29[42]です。

今深刻なメモです。 常にスレッドプールを使用するだけです。

1)あなたが長い*処理*タスクを持っているなら(すなわち。 複数のワークピースの食事に分割できる場合は、タスクを分割してから個々のワークアイテムをすべてhttp://msdn.microsoft.com/ja-jp/library/system.threading.threadpool.queueuserworkitemに送信する必要があります。 .aspx [ThreadPool]。 スレッドプールは、必要に応じて新しいスレッドを開始するなどの自己監視機能を備えているため、動的にワークアイテムを拾い上げ、それらを動的に検索し始めます。 .aspx#scalenetchapt17_topic14(開発時に数値を事前計算するのではなく)[配置サイトの要件に従って管理者によって配置時に設定されます]。 処理タスクの適切なパーティショニングサイズが利用可能なCPUの数を考慮に入れることができるというのは本当ですが、正しい答えはタスクの性質とこの段階で話す価値がないデータに大きく依存します。主な関心事はあなたの NUMA nodes、メモリの局所性、そしてインターロックされたキャッシュの競合であり、それ以降はコアの数です。

2)I / O(DB呼び出しを含む)を実行している場合は、非同期I / Oを使用し、完了ルーチンと呼ばれるThreadPoolで呼び出しを完了する必要があります。

これら2つがあなたが複数のスレッドを持つべきである唯一の正当な理由であり、それらはどちらもThreadPoolを使用することによって最もよく処理されます。 'request’または 'connection’ごとにスレッドを開始することを含め、それ以外のものはすべて、実際にはWin32 APIの世界ではアンチパターンです(forkは* nixでは有効なパターンですが、Windowsでは絶対にできません)。

トピックに関するより専門的な方法、方法、詳細な説明については、このトピックに関するRick Vicikの論文のみをお勧めします。


3


あなたが完全にCPUに縛られていることを考えると、経験則の良いルールは `+ processorCount + 1 +`です。

常にいくつかのタスクが開始/停止/中断され、 `+ n `タスクが ` n +`プロセッサを完全にいっぱいにすることはないため、これは_ + 1_です。


3


最適な数は、単にプロセッサ数です。 コンテキスト切り替えとそれに伴うオーバーヘッドを最小限に抑えるために、常に1つのスレッドをCPU(論理的または物理的)上で実行するのが最適です。

それが正しい数であるかどうかは、あなたがしていることによります。 スレッドプールは(私が正しく理解していれば)できるだけ少ないスレッドを使用しようとしますが、スレッドがブロックするたびに別のスレッドをスピンアップします。

ブロッキングは決して最適ではありませんが、何らかの形でブロッキングを行っている場合、答えは劇的に変わります。

良い(必ずしも最適ではない)動作を実現するための最も簡単で簡単な方法は、スレッドプールを使用することです。 私の意見では、スレッドプールよりもうまくやるのは本当に難しいので、単に開始するのに最適な場所であり、それが十分ではない理由を示すことができるのであれば、他のことについて考えることができます。


2


唯一の方法は、パフォーマンスデータに基づくデータとコード分析の組み合わせです。

異なるCPUファミリと速度 メモリ速度とシステム上の他のアクティビティとのすべてが、チューニングを異なるものにします。

潜在的にはいくらかの自己調整が可能ですが、これは何らかの形のライブパフォーマンスの調整と自己調整を持つことを意味します。


2


ThreadPoolよりも優れている場合は、TPLの.NET 4.0 Taskインスタンスを使用します。 タスク並列ライブラリは.NET 4.0フレームワークの基盤の上に構築されており、タスクをできるだけ効率的に実行するために最適なスレッド数を実際に決定します。


1


私は最近これについて何かを読みました(例えば この質問に受け入れられた答えを見てください)。

簡単な答えは、オペレーティングシステムに決めさせることです。 それはあなたができるよりも何が最適であるかを決めるというはるかに良い仕事をすることができます。

似たようなテーマについて多くの質問があります - 「最適な数のスレッド」を検索すると(引用符は含みません)、数ページの結果が得られます。


1


http://msdn.microsoft.com/ja-jp/library/system.environmentのいずれかを使用して、サーバーアプリケーションを作成した後にCPUからすべて使用できる場合は、実行している内容によっても異なります。 .processorcount.aspx [Environment.ProcessorCount]またはスレッドプールは良い考えです。 しかし、これがデスクトップまたはこのタスク専用ではないマシンで実行されている場合は、マシンがユーザーのために「機能する」ように、CPUをアイドル状態にしておくことをお勧めします。


0


最良のスレッド数を選択する本当の方法は、アプリケーションが自分自身をプロファイリングし、最適なパフォーマンスが得られるものに基づいてそのスレッド化動作を適応的に変更することです。