2012-02-13 4 views
6

Я пытаюсь собрать информацию о моем CPU с __cpuid(). Несмотря на то, что он правильно работает на моем компьютере, когда я запускаю свою программу на компьютере моего коллеги, он обнаруживает, что Intel Core2 Quad Q6600 является гиперпоточным, хотя, согласно спецификациям на собственном сайте Intel, это не так.Использование CPUID для определения спецификаций CPU, надежное решение?

__cpuid() также обнаруживает неправильное количество «логических сердечников», как показано здесь: Programmatically detect number of physical processors/cores or if hyper-threading is active on Windows, Mac and Linux. Где он утверждает, что Intel Xeon E5520 имеет 16 логических ядер и 8 физических.

Я попытался запустить код, найденный в этой теме на моем собственном компьютере, Intel i7 2600K, давая мне те же номера, что и для Xeon.

Итак, насколько надежным является __cpuid() действительно? По моему собственному опыту это не кажется таким надежным. У меня что-то очень фундаментальное?

+0

Если вы не склонны использовать __cpuid(). Вы можете использовать OpenMPs omp_get_num_procs(), который должен возвращать количество потоков, которые ваш процессор может запускать одновременно. Я не знаю, насколько достоверна эта информация. У меня никогда не было таких проблем. – Compuholic

+0

CPUID обычно достаточно надежный, но иногда он может вводить в заблуждение или неверно. Ваш процессор может очень хорошо поддерживать одну функцию, но ваша материнская плата не отключена (или отключена), поэтому она будет представлена ​​как присутствующая, но не работает. Есть библиотеки, которые берут CPUID и пытаются сделать его немного более надежным, с базой данных исправлений и т. Д. – Kitsune

+0

Но если ЦП не поддерживает Hyperthreading и CPUID, давая вам информацию о том, что он присутствует, это действительно проблема с материнской платой, я мог видеть, что это наоборот, где ЦП поддерживает HTT, но не материнскую плату и те вы получаете ложь при проверке HTT. – Alex

ответ

3

CPUID можно доверять, вам просто нужно использовать его правильно. в этом случае это означает правильное перечисление топологии. вы получаете 16 логических процессоров, потому что поле, полученное от него, представляет собой максимум, который он может поддерживать, а не то, сколько на самом деле есть. значение, полученное для ядер, фактически является логическим числом.

Код в теме является очень простым и подразумевается как отправная точка, в моей системе (i7 2720QM) я также записываю недействительные данные, но используя свой собственный код, который проверяет топологию в соответствии с сопоставлениями CPU CPUID, я получаю правильный Результаты.

1

Существует почти наверняка пробел в [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, когда я нашел ваш вопрос.