とぴやまのブログ(アーカイブ)

元はてなダイアリー

Windowsで実行中のスレッドが動作している論理CPU番号を取得するには

下記URLの内容より。

https://www.cs.tcd.ie/Jeremy.Jones/GetCurrentProcessorNumberXP.htm
GetCurrentProcessorNumber XP


マルチプロセッサ環境の Windows アプリケーションにおいて、実行中のスレッドがどのCPUで動作しているかを判断するにはどうするか。

GetCurrentProcessorNumber という API があるが、Windows Vista, Windows Server 2003 以上でしか対応しておらず、Windows XP には対応していないので使用できない。


GetCurrentProcessorNumber Function (Windows) (※Windows Vista, Windows Server 2003 以上)

DWORD WINAPI GetCurrentProcessorNumber(void);

GetCurrentProcessorNumberEx Function (Windows) (※Windows 7, Windows Server 2008 R2 以上)

VOID GetCurrentProcessorNumberEx(__out  PPROCESSOR_NUMBER ProcNumber);


Windows XP で実現するために、これ以外の方法はないだろうか? ということで、分かったのが CPUID 命令。

EAX = 1 にして実行した時に EBX[31:24] に格納される値が、論理CPU番号になる。

DWORD GetCurrentProcessorNumberXP(void)
{
  _asm {mov eax, 1}
  _asm {cpuid}
  _asm {shr ebx, 24}
  _asm {mov eax, ebx}
}

但しこの CPUID 命令自体も Pentium 4 以降でしか対応していないので、CPU 種別の判別処理が必要になる。これにはどう対応すればいいのだろうか? 同じく EAX = 1 の CPUID 命令 での EBX[7:0] ブランド ID 値だろうか? これも昔の CPU では対応していない場合もある。泥沼だ……。

参照:
CPUID (命令) - 通信用語の基礎知識
インテル プロセッサの識別とCPUID命令 (※PDFファイル直リン注意!)
CPUID Modifications for AMD Processors (※AMD CPU の場合)