ほぼ確実に、プロセッサの [x2]APIC ID にギャップがあります。これは、APIC ID の一部の値がどの論理プロセッサにもマップされていないことを意味します。cpuid の 0xB リーフを使用して調べる必要があります。手順については、インテルのリファレンス コードとアルゴリズム ( https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/ ) を参照してください。 EAX=0xB、ECX=0 でコアごとの論理プロセッサ (スレッド) の数を EBX で取得してから、EAX=0xB、ECX=1 で cpuid を再度呼び出し、プロセッサ パッケージごとの論理プロセッサの数を EBX で取得します。
リーフ 0x1 を使用する古い方法では、APIC ID のギャップを考慮することができません。残念ながら、これは MSDN Visual C++ 2013 リファレンス ページ ( http://msdn.microsoft.com/en-us/library/hskdteyh.aspx ) で提供されているサンプル コードであり、2010 年以降に製造されたプロセッサでは正しくありません。 MSDN のコードを使用したのか、他の場所の同様に間違ったコードを使用したのかがわかります。問題を理解するのに苦労した後、最近更新した cpuid に関するウィキペディアのページには、APIC id ギャップのあるプロセッサのトポロジを列挙するための「Intel スレッド/コアおよびキャッシュ トポロジ」のセクションに、完成した例があります。 APIC ID のどのビットが実際に使用され、どのビットが「デッド」であるかを判断する方法など、追加の詳細が含まれています。
Microsoft が __cpuid() ページで現在提供しているコード サンプルを考えると、これは基本的に論理 CPU カウントが 4 ではなく 16 を返すのと同じ質問です。これは、Intel 仕様の同じ解釈エラーに根ざしているためです。MSDN の貧弱なショーの説明として、彼らが提供するコードは 2010 年頃までは問題なく機能していました。この古いビデオ/記事でわかるように、インテルは x2APIC が導入される前に同様の方法を提供していました: https://software.intel.com/en-us/articles/hyper-threading-technology-and-multi-core -processor-detection __cpuid に関するさまざまなバージョンの MSDN ページを見ると、それらのコード サンプルは基本的に 2008 年から同じままです...
単一のハイパースレッディング検出ビットに関しては、それはより長い話であり、ハイパースレッディングがプロセッサなしでサポートされていると報告されるのはなぜですか? . 簡単に言えば、プロセッサ パッケージが複数の論理プロセッサをサポートしているかどうかは、どちらかといえばレガシー ビットによってわかります。したがって、ビットの名前は誤解を招く可能性があります。
また、質問のタイトルを「CPUID を使用して CPUトポロジーを検出する、信頼できるソリューションですか?」に変更することをお勧めします。あなたの質問を完全に偶然見つけたからです。あなたの質問を見つけたとき、Google で Sandy Bridge cpuid dumps を検索していました。