4

NT サービスを Intel Core2 ベースの Win2k3 マシンで実行し、すべての論理 CPU (プロセス アフィニティのすべてのビット) を反復処理する必要があります。そのために、GetProcessAffinityMask() を呼び出してシステム アフィニティ マスクを取得し、プロセスを各プロセッサに順番に切り替えます。

 DWORD systemMask;
 GetProcessAffinityMask( ... &systemMask );
 DWORD processorId = 1;
 while( systemMask != 0 ) {
    SetProcessAffinityMask(... processorId );
    Sleep( 1 ); // to be sure that it shifts to that processor
    systemMask >>= 1;
    processorId <<= 1;
 }

各反復で、ここからコードを呼び出して、現在のプロセッサ APIC ID を取得します。問題は、プロセッサが異なると、同じ APIC ID が返される場合があることです。ドキュメントによると、システム内の各プロセッサは同一の ID を持つ必要があります。

これをデバッグしてみました-Windowsが実際にアフィニティを変更するかどうかを確認しました:

 while( systemMask != 0 ) {
    SetProcessAffinityMask(... processorId );
    Sleep( 1 ); // to be sure that it shifts to that processor
    DWORD tempAffinity;
    GetProcessAffinityMask( ... &tempAffinity );
    // run APIC id detection code here
    systemMask >>= 1;
    processorId <<= 1;
 }

予想どおりのアフィニティ マスクが返されますが、APIC ID は異なるプロセッサでも同じである可能性があります。

この奇妙な状況に説明はありますか?

4

4 に答える 4

2

Windows API 呼び出しを使用してこれを判断することはできません。

まず、Intel CPU (AMD などについては不明) の APCID は、EAX = 0x1 で CPUID を呼び出した後、最初は EBX レジスタ (ビット 24 ~ 31) の 8 ビット セクション (EBX[31:24]) 内にエンコードされます。

インライン アセンブリを含む次の C/C++ コードを考えてみましょう。

unsigned int cpu_eax;
unsigned int cpu_ebx;
unsigned int cpu_ecx;
unsigned int cpu_edx;
unsigned int apic_id;

__asm
{
  mov    eax, 0x1
  cpuid
  mov     [cpu_eax], eax
  mov     [cpu_ebx], ebx
  mov     [cpu_ecx], ecx
  mov     [cpu_edx], edx
}

apic_id = ( cpu_ebx & 0xFF000000) >> 24; 

GetProcessAffinityMask は、使用可能なすべてのコア、CPU 内のコア、および CPU ごとのハイパースレッド対応コアを単純に列挙し、これらの組み合わせの合計を返します。物理 CPU と CPU 内のコアとハイパースレッド対応コアの概念はありません。少なくとも、そのようには報告されていません。

于 2011-02-04T03:01:14.350 に答える
1

DPC を別の CPU にポストし、DPC プロデューサーで操作を行うことができます。

于 2011-12-12T02:31:16.040 に答える
1

これは、MSVC++ インライン __asm ステートメントで cpuid を使用できないためです。これは、レジスターを破棄するためです (つまり、コンパイラーが eax に変数を格納したため、コンパイラーの背後でレジスターを変更した cpuid を呼び出しました)。MSVC++ コンパイラにはGCC の clobber listに相当するものがないため、機能しません。

現在実行中の CPU を特定するには、別の方法を使用する必要がありますが、頭の中で考えると、良い方法が思い浮かびません...

編集:また、なぜ APIC ID を気にするのですか? n 個のプロセッサで同じコードを n 回連続して実行したいだけなら、アフィニティ、スリープ、アフィニティのインクリメント、スリープなどを設定できませんか?

于 2009-09-15T02:06:59.883 に答える
0

ループの最初の反復では、アフィニティ マスクを 0 に設定したようです。MSDN のドキュメントでは、その場合の動作を明確に指定していませんが、その場合はどこでもスレッドを実行できるはずです。 .

于 2009-09-18T22:37:13.433 に答える