Существует почти наверняка пробел в [x2] APIC-идентификаторах на вашем процессоре, что означает, что некоторое значение идентификаторов APIC не сопоставляется ни с одним логическим процессором. Вы должны использовать лист cxuid 0xB, чтобы узнать. Вы можете посмотреть эталонный код и алгоритм Intel (https://software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration/) для шагов, но он доходит до вызова с EAX = 0xB, ECX = 0 и получает в EBX количество логических процессоров (потоков) на ядро, а затем снова вызывает cpuid с EAX = 0xB, ECX = 1 и получением в EBX количества логических процессоров на процессорный пакет.
Старый способ использования листа 0x1 не может учитывать пробелы идентификатора APIC. Увы, это пример кода, который все еще содержится на странице справки MSDN Visual C++ 2013 (http://msdn.microsoft.com/en-us/library/hskdteyh.aspx) и , это неверно для процессоров, сделанных в 2010 году, а затем, поскольку вы узнали, используете ли код из MSDN или аналогично неправильный код из других источников , На странице Wikipedia на cpuid, которую я недавно обновил после того, как я попытался понять эту проблему, теперь есть разработанный пример в разделе «Intel thread/core и топология кеша» для перечисления топологии на процессоре с пробелами идентификатора APIC, с дополнительными сведениями, в том числе о том, как определить, какие биты идентификаторов APIC фактически используются и которые «мертвы».
Учитывая пример кода, предлагаемый Microsoft на странице __cpuid(), это в основном тот же вопрос, что и Logical CPU count return 16 instead of 4, поскольку он внедрен в ту же интерпретационную ошибку спецификаций Intel. В качестве объяснения плохого шоу MSDN, код, который они предлагают, работал нормально до 2010 года или около того; Intel использовала аналогичный метод до того, как был представлен x2APIC, как вы можете видеть в этом старом видео/статье: https://software.intel.com/en-us/articles/hyper-threading-technology-and-multi-core-processor-detection Если вы посмотрите на различные версии страницы MSDN на __cpuid, их образец кода в основном остался прежним с 2008 года. .
Что касается отдельного бита обнаружения гиперпотока, то это более длинный рассказ, уже ответивший на меня по телефону Why does Hyper-threading get reported as supported on processors without it?. Вкратце заключается в том, что этот довольно устаревший бит говорит вам, поддерживает ли процессор пакет более одного логического процессора, будь то с помощью hypetreading или многоядерных технологий. Таким образом, имя бита вводит в заблуждение.
Кроме того, я предлагаю изменить заголовок вашего вопроса на «Использование CPUID для определения CPU топологии, надежное решение?» потому что я нашел ваш вопрос совершенно случайно. Я искал Sandy Bridge cpuid dumps на google, когда я нашел ваш вопрос.
Если вы не склонны использовать __cpuid(). Вы можете использовать OpenMPs omp_get_num_procs(), который должен возвращать количество потоков, которые ваш процессор может запускать одновременно. Я не знаю, насколько достоверна эта информация. У меня никогда не было таких проблем. – Compuholic
CPUID обычно достаточно надежный, но иногда он может вводить в заблуждение или неверно. Ваш процессор может очень хорошо поддерживать одну функцию, но ваша материнская плата не отключена (или отключена), поэтому она будет представлена как присутствующая, но не работает. Есть библиотеки, которые берут CPUID и пытаются сделать его немного более надежным, с базой данных исправлений и т. Д. – Kitsune
Но если ЦП не поддерживает Hyperthreading и CPUID, давая вам информацию о том, что он присутствует, это действительно проблема с материнской платой, я мог видеть, что это наоборот, где ЦП поддерживает HTT, но не материнскую плату и те вы получаете ложь при проверке HTT. – Alex