2012-01-25 29 views
16

特定のスレッドが実行されているCPUを特定する方法はありますか? C#では可能ですが、C++では可能です。スレッドが実行されているCPUを特定するにはどうすればよいですか?

.NET ProcessおよびProcessThreadクラスは、この情報を提供していないようです。

ETA明確化:

私たちは、HTTPマルチキャストストリームを処理し、複数のビデオエンコーダを生成しますサーバーアプリケーションを開発しています。これは12個の物理コアを持つシステム上で実行され、結果として24個の論理CPU(ハイパースレッディング)が発生します。 TaskManagerとProcessExplorerを使用して、生成されたプロセスが論理CPU上で均等に分散されていることを確認しました。しかし、私たちは、CPU時間の異常な量を食べることによって干渉する1つのCPU上で(カーネル?)活動の多くを見ている。この特定のCPUで実行されているプロセス(またはスレッド)を特定しようとしています。 TaskManagerもProcessExplorerもその情報を提供していないようです。もしそうなら、そのような情報がどのように得られるかを説明してください。

それ以外の場合は、この情報を取得するための独自のツールを作成することを検討しています。それが私たちが助けを必要とするものです。

スレッドアフィニティを変更する方法はわかっています(この特定のケースでは、CPUを使い果たしているスレッドは1つのCPUにしか関連付けられていませんが、スレッドがどのCPUにも関連付けられるという保証はありません)、しかしそうするためには、最初にどのプロセス/スレッドの再配置が必要かを判断する必要があります。それがこの質問の唯一の目的です。

これが問題の明確化に役立つことを望みます。

+7

この情報でどのような問題を解決しようとしていますか? –

+0

それはカーナルだけに知られています。だからあなたはカーネルモードでプログラムする必要があります。 MSDNでKernal APIを探します。 – Nawaz

+2

異なる時間に多くの異なるCPU上でスレッドが実行された場合、どのようにしたいでしょうか? –

答えて

2

MSDNからProcessThread.ProcessorAffinityプロパティを使用すると、にはを設定できますが、取得できません。デフォルトでは、スレッドは親和性を持たない(任意のプロセッサ上で動作可能)。

using System; 
using System.Diagnostics; 

namespace ProcessThreadIdealProcessor 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Make sure there is an instance of notepad running. 
      Process[] notepads = Process.GetProcessesByName("notepad"); 
      if (notepads.Length == 0) 
       Process.Start("notepad"); 
      ProcessThreadCollection threads; 
      //Process[] notepads; 
      // Retrieve the Notepad processes. 
      notepads = Process.GetProcessesByName("Notepad"); 
      // Get the ProcessThread collection for the first instance 
      threads = notepads[0].Threads; 
      // Set the properties on the first ProcessThread in the collection 
      threads[0].IdealProcessor = 0; 
      threads[0].ProcessorAffinity = (IntPtr)1; 
     } 
    } 
} 

Thread.SetProcessorAffinityも同じことをします。

+1

さらに、スレッドAREは動き回っているので、答えを得ても何かをチェックしようとすると必ずしも有効ではありません。 – TomTom

+0

ええ、ProcessとProcessThreadのProcessorAffinityプロパティが私の最初の希望でしたが、あなたが指摘したように、私はそれを得ることができません... – Harald

+0

@TomTom:はい、それらは移動できますが、私たちの場合、貴重な情報 – Harald

2

これは、信頼性の高い方法で連続して行うことはできません。 OSタスクスケジューラはスレッドを最適化し、使用可能なCPUコア間で負荷を分割します。一般的に、スレッドは任意のCPU上で実行できます。さらにコンテキストスイッチを使用すると、CPUを変更することもできます。

特定のスレッドまたはプロセスを特定する必要がある場合は、アフィニティのみを割り当てることができるため、特定の論理CPU上でプロセス/スレッドが実行されることを期待できます。

+0

技術的には間違いありませんが、答えは非常に重要ではありません。現在のCPUを知ることで**共有リソースをバケット化することで競合を大幅に削減**することができます。はい、まれに、中断して他のコアに移動します。これは、同期がまだ必要であることを意味します。しかし、パフォーマンスの結果は比類のないものです。 –

+0

@KirillKobelevあなたに私にこれについてのいくつかの参考文献を教えてください。私はそれが低レベルで動作しているのを見ることができますが、アプリケーションからこれをどのように管理できるかはわかりません。 NUMAについて話していますか? – oleksii

+0

'int cnt [num_cores];のパフォーマンスについて考えてみましょう。 InterlockedIncrement(cnt [GetCurrCore()]); '単純なバージョンでカウンタが1つだけの場合。 –

関連する問題