Компания
409,52
рейтинг
15 мая 2014 в 09:04

Разработка → (Само)идентификация процессоров. Часть вторая. Волосатый CPUID

В первой части я рассказал о необходимости идентификации расширений, присутствующих на конкретном процессоре. Это нужно для того, чтобы исполняющийся код (операционная система, компилятор или пользовательское приложение) смог надёжно определить, какие возможности аппаратуры он может задействовать. Также в предыдущей статье я сравнил несколько популярных архитектур центральных процессоров общего назначения. Возможности по идентификации между ними сильно разнятся: некоторые предоставляют полную информацию о расширениях ISA, тогда как другие ограничиваются парой чисел для различения вендора и ревизии.
В этой части я расскажу об одной инструкции архитектуры Intel IA-32 — CPUID, введённой специально для перечисления декларируемых процессором расширений. Немного о том, что было до её появления, что она умеет сообщать, какие неожиданности могут поджидать и какой софт позволяет интерпретировать её вывод.


Источник изображения: [1]


История


Как я уже утверждал в первой части, присутствует следующая тенденция: чем более «встраиваемая» природа у процессора, тем меньше возможностей для идентификации заложено в его архитектуру. Создатели встраиваемых систем почему-то не волнуются о переносимости двоичного кода.

Не являлся исключением и Intel 8086 — микропроцессор 1970-х годов, выросший из «калькуляторной» серии 8008, 8080, 8085. Изначально в него не было заложено никаких средств идентификации.
Начиная с 808386 сведения о модели, степпинге и семействе стали сообщаться в регистре EDX сразу после перезагрузки (получения сигнала RESET). Инструкция CPUID, кодируемая байтами 0x0f 0xa2, была введена в процессорах 80486. Наличие CPUID можно было распознать по возможности записи в бит 21 регистра флагов. Для поддержки работы на более старых ЦПУ приходилось идти на очень изощрённые методы для того, чтобы различать процессоры серий от 8086 до 80386.

CPUID algorithm wars (1996)
В статье [2] от 1996 года Роберт Коллинс предложил алгоритм для различения всех существовавших на тот момент продуктов IA-32 от Intel. Его не устраивал официальный метод идентификации от Intel, основанный только на различии в поведении инструкции PUSH SP (об этом чуть ниже), так как он не был универсальным. В своих работах Роберт предлагал задействовать следующие дополнительные трюки.
  • Исполнять инструкции, не присутствующие на всех процессорах, перехватывая исключение #UD. Зная, какие инструкции не сгенерировали исключение, можно определить семейство процессора. Однако, для 8086/8088 такой подход не сработал бы, так как в них не было определено поведение для неподдерживаемых команд.
  • Инструкция PUSH SP работает по-разному на 8086 и 80286. На первом ЦПУ на стек попадает значение регистра SP до изменения его значения. На 80286 эта ошибка была исправлена:
    «The iAPX 286 will push a different value on the stack for PUSH SP than the iAPX 86/88.»
  • 80186 также кладёт неправильное значение SP на стек, но при этом поддерживает CPUID.
  • Запись слова (16 бит) в сегмент по смещению 0xffff (т.е. начиная с последнего адресуемого байта) на 8086 процессоре приведёт к тому, что второй байт этого слова попадёт в память по смещению 0, тогда как на 80186 этот байт пойдёт за границу сегмента по смещению 0x10000.
  • Некоторые клоны Intel Pentium поддерживали CPUID, но не сообщали об этом в помощью бита 21 регистра флагов, противореча документации, или же позволяли динамически включать поддержку этой инструкции после загрузки.
  • Различение моделей процессоров с одной и той же «цифрой» (например, между 80386 DX и 808386 SX, CX, EX, SL или Intel Pentium P5, P54C, OverDrive) также требовало аккуратного учёта различий в поддерживаемых расширениях.
  • 80386 DX и SX можно различить по разнице в количестве модифицируемых бит регистра CR0.
  • Некоторая информация об идентификации могла быть получена с помощью документированной серии операций на портах ввода-вывода (инструкции IN/OUT).
  • Различия между моделями 80486 могли быть получены с помощью проверки наличия математического сопроцессора 80487.

Для получения информации о степпинге на 80386 необходимо прочитать значение EDX сразу после RESET'а. Но в этот момент начинает работать BIOS, который наверняка перезапишет этот регистр задолго до того, как управление будет передано пользовательскому коду! Однако и тут Роберт придумывает и описывает хитрую схему с манипуляцией печально известной линией A20 для того, чтобы обмануть процесс перезагрузки и получить управление.

Перечисленные в оригинальной статье техники были опробованы преимущественно на ЦПУ от Intel. В статье автор признаёт, что они не позволяют надёжно классифицировать клоны x86 других производителей.


Интерфейс


Для системного программиста работа по идентификации некоторого расширения обычно заключается в установке входных значений в регистрах EAX (лист, англ. leaf) и ECX (подлист, англ. subleaf), исполнению CPUID и прочтению результата в четырёх регистрах: EAX, EBX, ECX, EDX. Отдельные битовые поля выходных регистров будут содержать информацию о значениях связанных с ними архитектурных параметров конкретного ядра процессора.

Все валидные сочетания входных листов-подлистов и четвёрок регистров на выходе формируют таблицу CPUID. Для современных процессоров она содержит около двух десятков строк по четыре 32-битных столбца.
Я не буду расписывать детально все официально описанные поля этой таблицы. Интересующиеся всегда могут найти их в Intel SDM [1] (рекомендую запастись терпением — около 40 страниц текста только про CPUID). Болеее того, для уже заявленных, но ещё не выпущенных в физических продуктах расширений ISA соответствующие им новые поля CPUID могут быть найдены в [3]. Вместо этого я классифицирую информацию, которую можно извлечь из вывода этой инструкции. Для обозначения битовых полей таблицы я буду использовать принятую для этого нотацию: CPUID.leaf.subleaf.reg[bitstart:bitend]. Например, CPUID.0.EBX[31:0] — это биты с 0 по 31 выходного регистра EBX после исполнения CPUID, которая на вход получила лист 0 (EAX = 0); подлист (входное значение ECX) игнорируется, поэтому он не указан.

Регионы листов

Неподдерживаемые значения входных EAX и ECX не приводят к возникновению исключений, а вместо этого возвращают нули во всех четырёх регистрах, либо «мусор» (значения другого листа согласно спецификации). Допустимые же сочетания листов и подлистов образуют три непрерывных региона.



  • Обычный регион — все листы с номерами, начиная с нулевого и до максимального значения, равного CPUID.0.EAX[31:0]. Номер максимального листа постоянно растёт и уже давно перевалил за десятку.
  • Расширенный регион — все листы, начиная с 0x80000000 и до максимального значения, равного CPUID.0x80000000.EAX[31:0]. Довольно долгое время это максимальное значение остаётся равным 0x80000008. Я не нашёл документальных доказательств, но у меня есть чувство, что само появление диапазона расширенных листов связанно с введением компанией AMD 64-битного расширения архитектуры IA-32.
  • Диапазон листов 0x40000000-0x4fffffff считается зарезервированным; обещается, что возвращаемые для него CPUID значения всегда будут равны нулю. Однако это не мешает некоторым использовать его для своих нужд. Например, виртуальные машины KVM возвращают в листе 0x40000000 четвёрку чисел [0, 0x4b4d564b, 0x564b4d56, 0x4d].
    Скрытый текст
    Это ASCII-строка «KVMKVMKVM»



ISA

Наиболее важные для практиков данные, закодированные в CPUID — это флаги поддерживаемых наборов инструкций. Традиционно для этого отводились биты в составе CPUID.1.ECX и CPUID.1.EDX. Несколько примеров ниже.
  • CPUID.1.ECX[0] — SSE3 — векторные инструкции.
  • CPUID.1.ECX[9] — SSSE3 — другие векторные инструкции.
  • CPUID.1.ECX[7] — EIST — Enhanced Intel SpeedStep®, динамическое изменение частоты процессора.
  • CPUID.1.EDX[25] — SSE — ещё векторные инструкции.
  • CPUID.1.EDX[26] — SSE2 — снова векторные инструкции.

Однако в настоящее время расширения ISA могут быть обозначены битами в других листах, так как ёмкость листа 1 исчерпана.
  • CPUID.6.EAX[1] — Intel Turbo Boost, оверклокинг «из коробки».
  • CPUID.7.0.EBX[4] — Hardware Lock Elision, CPUID.7.0.EBX[11] — Restricted Transactional Memory — два расширения от Intel для поддержки транзакционной памяти.
  • CPUID.0x80000001.ECX[5] — LZCNT, инструкция для подсчёта числа старших нулевых бит, похожая (даже слишком) на BSR.

Brand String

Конечно же, ни один вендор не упустит возможности увековечить своё имя в идентификационных данных своего продукта. Причём желательно сделать это не просто в виде числа, а впечатать ASCII-строку (хорошо хоть, что не Unicode).
В IA-32 CPUID текст можно найти минимум в двух группах листов. CPUID.0.EBX, ECX, EDX содержат 12 байт ASCII-строки, специфичной для каждого вендора. Для Intel это, конечно же, «GenuineIntel». А три листа CPUID.0x80000002–0x80000004 предоставляют аж 48 байт для кодирования в ASCII так называемой Brand String. Именно её видно при распечатке cat /proc/cpuinfo в Linux. И, хотя формат её более-менее стандартизован: «вендор марка серия CPU @ частота», я настоятельно не рекомендую по её содержимому принимать решения в программном коде. Слишком значительно её содержимое может варьироваться: частота может быть указана в МГц или в ГГц (а в реальности быть совсем иной из-за динамической подстройки), пробелы могут менять положение, а симулятор или виртуальная машина могут подставить туда вообще что угодно. Вся информация из brand string может быть найдена программно более надёжными способами.

Кэши

Информация о кэшах, такая как их тип, количество, ёмкость, геометрия, разделяемость между ядрами полезна для тюнинга высокопроизводительного математического софта, например, библиотек BLAS (basic linear algebra system).
Изначально конфигурацию кэшей описывал лист 2. Спроектировали его не очень дальновидно. Формат кодирования информации в нём был выбран не самый гибкий, он не смог в будущем поддержать постоянные изменения в объёме и конфигурации нескольких уровней кэшей. В настоящее время использование информации из листа 2 не рекомендуется, там могут стоять 0xFF-ки.
Судя по тому, что лист 0x80000006 входит в расширенный диапазон (хотя я не уверен, документальных доказательств пока что не нашёл), он был добавлен не Intel. С помощью него была сделана попытка информацию листа 2 дополнить данными о строении кэшей, которые потребовались разработчикам софта. При этом опять же не было намерения предоставить пространство для роста.
Лист 4 — последнее и пока что наиболее гибкое представление данных о кэшах. Цена этому — добавление концепции подлистов, кодируемых в ECX. Каждый подлист описывает один кэш: данных, кода или совмещённый, определяет его уровень, ёмкость и т.д. Хватит ли четвёртого листа надолго — поживём, увидим.

Топология

Под «топологией» здесь подразумевается, конечно, не раздел математики, а информация о взаимном расположении отдельных ядер и гипер-потоков (если поддерживается Intel HyperThreading) в составе текущего процессора. Для современных серверных процессоров Intel выделяются следующие уровни иерархии.
  • SMT — уровень гипер-потока, сущности, содержащей индивидуальное архитектурное состояние (регистры), но потенциально разделяющей исполнительные устройства с другими потоками (в составе одного ядра).
  • Ядро (core) — сущность, содержащая индивидуальный набор вычислительных устройств (сумматоров, умножителей и т.д.). Одно ядро может иметь в себе один, два (у ЦПУ с HyperThreading) или четыре (у Xeon Phi) гипер-потока.
  • Пакет (пэкадж, package) — собственно железка целиком, покупаемая в магазине и вставляемая в разъём (сокет) на матплате. Имеет на себе как минимум одно ядро. В многопроцессорных серверных системах может быть несколько пэкаджей.

Понятие «логический процессор» соответствует самому нижнему из присутствующих в системе уровней. Именно их видит операционная система. От того, являются ли два логических процессора родственниками (т.е. входят в состав одного ядра или пакета), зависит стоимость миграции процессов между ними, задержки при передаче данных, эффекты кэшей, конфигурация NUMA-памяти и т.п. Именно поэтому данные о топологии содержатся в CPUID листе 0xB и его подлистах.
Кроме того, для задач адресации для доставки прерываний от периферийных устройств и других процессоров, каждый логический процессор имеет т.н. APIC ID — уникальное в составе системы число. Топология влияет на то, по какому закону выдаются эти числа множеству активных ядер. Они не всегда последовательны; например, в системе с выключенным HyperThreading все APIC ID будут чётными.
Классический APIC ID хранится в поле CPUID.1.EBX[31:24]. Это всего 8 бит, что ограничивает число логических процессоров 256, что, конечно, недостаточно в современных реалиях. Поэтому существует его расширение — X2APIC ID, хранимое в CPUID.0xB.EDX[31:0]. Думаю, что этих 32 бит хватит на более длительный период.
«Координаты» каждого логического процессора в топологии его пэкажда уникальны. По этой причине неплохо бы озаботиться обеспечением affinity для потока, читающего несколько листов CPUID подряд, иначе он рискует получить значения с разных ядер.

Изменяемые поля

Если проблем с топологией кажется мало, то спешу сообщить, что само содержимое таблицы CPUID может меняться динамически во время работы системы. Не все поля, конечно, можно изменить; и всё же из настроек BIOS можно напрямую влиять на то, увидит ли ОС некоторые возможности используемого ЦПУ. Приведу лишь некоторые из них.
  • Бит 18 регистра CR4 влияет на CPUID.1:ECX.OSXSAVE[27], обозначающий поддержку инструкции XSAVE.
  • Поля регистра IA32_MISC_ENABLE влияют сразу на несколько полей CPUID: бит 3 — на поля TM1 и TM2, бит 16 — на поле EIST, бит 34 — на поле XD (execution disable) и т.д.
  • Включение бита 22 регистра IA32_MISC_ENABLE вообще «отрезает» все листы таблиц CPUID старше третьего (видимо, это было сделано для совместимости с Windows NT4, не зря этот бит так и называется — NT4).


Разное

В этой секции я собрал прочие интересные моменты, связанные с историей и работой команды CPUID.

Processor Serial Number

Во времена Pentium III каждый процессор получил уникальный серийный номер, содержавшийся в CPUID.3.ECX и CPUID.3.EDX [7]. Легко представить, насколько такая фича была бы удобна для нужд защиты ПО от копирования. Однако в 1999 году Европейское сообщество запротестовало, разумно опасаясь, что подобная функциональность повредит приватности пользователей таких систем. Уже в Intel Pentium IV серийный номер был убран, сейчас лист 3 возвращает нули.

Вендоры и CPUID

Очень интересная таблица [5] повествует о том, что хранят (или в прошлом хранили) в разных листах CPUID разные вендоры. Например, описывается некий mystery level 0x8fffffff, в котором процессоры AMD K8 возвращали строку IT'S HAMMER TIME.

Agner Fog о войнах ISA

История появления расширений набора инструкций IA-32 в условиях конкурентной борьбы нескольких компаний [4]. Добавление новых инструкций всегда влияло на CPUID, и не всегда все могли договориться о том, как это сделать правильно.

Они испортили CPUID! IA32_BIOS_SIGN_ID

Инструкция CPUID всегда нравилась мне лаконичностью своего интерфейса и отсутствием неожиданностей в работе: один регистр на входе и четыре на выходе. В её работе нет генерации исключений, нет обращений к памяти, нет чтения/модификации регистра флагов, на неё не влияют префиксы, она работает во всех режимах процессора. По сравнению с зоопарком CISC-команд IA-32 это был почти идеал.
… пока не оказалось, что иногда на вход необходимо подать два регистра для кодирования листа и подлиста. Окей, не так всё хорошо. Ну хотя бы выходные регистры заранее известны и всегда изменяются…
И тут оказалось, что иногда CPUID изменяет ещё один регистр — а именно IA32_BIOS_SIGN_ID, — и сохраняет в нём сигнатуру текущей программы микрокода процессора. Происходит это, если до этого было произведено обновление прошивки процессора. По каким-то причинам информация об этой процедуре была раскидана по мануалу [1] на тысячу страниц, и потому она ускользала от меня очень долго.

Софт для чтения CPUID


В отличие от ряда других архитектур, в IA-32 инструкция CPUID непривилегированная, т.е. может быть исполнена пользовательским ПО, а не только ядром ОС. Поэтому обыкновенные программы могут свободно исследовать, какие возможности имеет ЦПУ, на котором они запускаются. Конечно же, было написано множество инструментов для представления запутанной двоичной информации CPUID в удобном для человека виде. Перечислю здесь некоторые.
  1. CPU-Z www.cpuid.com/softwares/cpu-z.html. Очень популярное приложение для идентификации для Windows. На мой вкус, слишком лаконичное.
  2. The CPUID Explorer. www.flounder.com/cpuid_explorer2.htm. Более подробное и потому удобное приложение для Windows. К сожалению, не обновлялось уже давно, поэтому не знает про современные поля CPUID. Это, кстати, общая проблема всех программ такого типа — они устаревают очень быстро.
  3. Intel® Processor Identification Utility для Windows: www.intel.com/support/processors/tools/piu/sb/CS-014921.htm. Официальное приложение от Intel, однако, умеет не очень много.
  4. msr-tools от Intel Open-source Technology Center: 01.org/msr-tools. Программы для получения значений CPUID и регистров MSR. По непонятным мне причинам чтение CPUID требует прав root; кроме того, вместо прямого вызова инструкции используются не самые надёжные интерфейсы ядра Linux.
  5. Ещё один cpuid для Linux: www.etallen.com/cpuid.html. Лучший образец, который я смог найти. Печатает подробную информацию обо всех флагах на всех логических процессорах.
  6. Я начал писать свой собственный велосипед: ggg-cpuid [6]. В отличие от прочих приложений, цель моего проекта — иметь возможность собирать идентификационную информацию на процессорах разных архитектур, не только IA-32. Сейчас работает на IA-32, IA-64 и ARM. По мере сил и при наличии времени буду добавлять разные системы.


Литература


  1. Intel Corporation. Intel® 64 and IA-32 Architectures Software Developer’s Manual. Volumes 1–3, 2014. www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html
  2. Robert R. Collins. CPUID algorithm wars. Dr. Dobbs Journal, November 1996. www.drdobbs.com/database/cpuid-algorithm-wars/184410005
  3. Intel® Architecture Instruction Set Extensions Programming Reference. software.intel.com/en-us/intel-isa-extensions
  4. Agner Fog. Stop the instruction set war. Agner`s CPU blog. www.agner.org/optimize/blog/read.php?i=25
  5. x86 architecture CPUID. sandpile.org/x86/cpuid.htm
  6. Grigory Rechistov. A set of CPU identification tools for Intel IA-32, IA-64 and other systems. github.com/grigory-rechistov/ggg-cpuid
  7. Intel Processor Identification and the CPUID Instruction. AP-485 Application Note, 1999. netwinder.osuosl.org/pub/misc/docs/i386/24161812.pdf
Автор: @Atakua
Intel
рейтинг 409,52

Комментарии (18)

  • +1
    + Определение топологии процессорной системы, бывает очень нужно для корректного распараллеливания:
    software.intel.com/en-us/articles/intel-64-architecture-processor-topology-enumeration
  • 0
    И еще сторонний вопрос — не попадалась ли тебе java оболочка для CPUID, позволяющая определять максимальное кол-во параметров? меня спрашивают разработчики приложений под Андроид, а я им кроме советов нативно компилировать, ничего сказать не могу.
    • +1
      Увы, не встречал. С другой стороны, если кому-то удастся из Джавы узнать возможности нижележащей аппаратуры, то воспользоваться ими всё-равно получится только через JNI. А раз есть JNI, то и CPUID из него можно позвать.
      Вот сформулировать аппаратно-независимый интерфейс для идентификации общих для многих архитектур расширений (векторы, шифрование, DSP) — это было бы интересно. Особенно если бы это оказалось полезным на практике, а для чего уже понадобятся библиотеки (или даже ОС), умеющие абстрагировать специфику ЦПУ.
    • +1
      Зачем нативно-то? Там вполне реалистично можно прочитать /proc/cpuinfo и оттуда вытащить тучу всего. Я на самом деле с трудом представляю, зачем на Android может понадобиться что-то, что оттуда вытащить нельзя.
      • 0
        В /proc/cpuinfo может не быть всей информации о процессоре.
        Например, если ядро у вас достаточно старое и не знает о существовании AVX, то оно разумеется не сможет отобразить AVX в /proc/cpuinfo даже, если железо его поддерживает.
        • 0
          Но в то же время, если ядро не поддерживает AVX, то пользоваться им в user-space нельзя, так как ядро не сохранит AVX регистры при переключении контекста.
          • +1
            Я бы сказал, что в данном случае это не безопасно.

            AVX наверно не лучший пример, вот Вам другой — AVX2. Ядро может знать о существовании AVX, но не подозревать о AVX2. При этом использование AVX2 будет абсолютно безопасным, но в /proc/cpuinfo оно отображено не будет.

            Моя идея состоит в том, что на /proc/cpuinfo пологаться не стоит.
    • +2
      Для Android у Marat Dukhan (Ph.D, Georgia Tech's College of Computing; SO) есть подпроект «Yeppp! CPUID for Android». Сам yeppp вроде бы включает в себя cpuid, и содержит "bindings for Java and .Net/Mono": docs.yeppp.info/java/ "Additionally, the library provides information about the CPU, such as processor vendor and microarchitecture, and an OS- and hardware-independent interface to processor cycle counters, and high-resolution timers.".

      Ага, на андроиде она парсит /proc/cpuinfo: bitbucket.org/MDukhan/yeppp/src/b8db687e912bbd7e2a26dd93c348ef2d7a5febdc/library/sources/library/CpuArm.cpp?at=default#cl-24

      Зато возможные флаги расписаны: Full list of ARM features reported in /proc/cpuinfo

      Размер кэша, например, эта библиотека получает из информации об архитектуре (Cortex- A5, A7, A8, A9, A15, ...):
      "There is no way to determine the cache size in user mode in Linux. So I make a best guess from the architecture. Guess about L1 cache size is almost always accurate, but L2 might be different on an actual platform."
      • 0
        Спасибо!
  • +2
    Если софт жестко подстраивать под архитектуру, то придется архитектуру определять постоянно, а то в гетерогенном кластере виртуальная машина может ВНЕЗАПНО смигрироваться на немного другой процессор (или заснуть на одном, а проснуться — на другом).
    • 0
      Если особенности аппаратуры определяются в начале работы программы и потом не меняются в процессе её работы до финиша, то грех ими не воспользоваться; не всё же для 386 без матсопроцессора писать. В случае ВМ с живой миграцией это действительно не так.
      Решений я вижу три: 1) монитор ВМ должен «утаивать» часть расширений, сводя допустимый набор к поддерживаемым самой старой машины облака, подводя все машины под общий знаменатель, но в таком случае появляется самое слабое звено по ISA; 2) монитор должен эмулировать на старых хостах недостающие инструкции, гарантируя сохранность ISA, но в таком случае скорость работы никакая.
      Мне кажется, правильное решение — 3) при миграции учитывать возможности используемых машин и выбирать приёмник для ВМ так, чтобы ISA не менялась, или, при невозможности сделать так, выдавать жирное предупреждение, но продолжать работать в режиме эмуляции.
      • 0
        На многих виртуализаторах (XEN и HyperV точно, про KVM и VMWare не скажу) команда CPUID отдает марку процессора = физическому, хотя число ядер под машину можно менять. Можно сделать такой странный одноядерный Xeon E5. К счастью, остальная периферия (чипсет, диски, видео) там эмулируется и всегда одинаковая.

        Мы как-то писали статью на тему «Повышение надежности SCADA путем запуска ее в облаке» и собрали «облако» или «кластер» из двух старых серверов CoreDuo и CeleronD под Xen. Дак WindowsXP даже не падала при переезде.

        Согласен с решением 3, при миграции в большом облаке надо учитывать что-то вроде affinity и мигрировать на ноды хотя бы такого-же поколения процессоров.
  • +6
    Пара мелких замечаний.

    1. CPUID всё-таки появился не в 80486м, а в P5 (коммерческое название — Pentium). Позже она была добавлена в P24C (коммерческое название — IntelDX4; «внутри» это вариант 80486 с несколькими новыми командами от P5).
    2. Расширенный регион связан с AMD, но конкретно с 64-битным расширением связан косвенно: AMD всегда использовала этот регион для своих расширений (начиная с 3DNBow! в K6-2), но Intel предпочитала всё эту деятельность игнорировать. Но когда Itanic накрылся медным тазом пришлось срочно заимствовать-таки x86-64 — вместе с соответствующими функциями CPUID…

    P.S. А ещё у AMD есть забавная особенность: Brand String в их процессорах нет вообще. То есть совсем. Фишка в том, что из одного и того же кристалла могут «выпекаться» совершенно разные CPU (в зависимости от того, сколько чего там работоспособно оказалось), да и коммерческое название процессора может меняться часто… решение — просто до гениальности: эта строка зашивается BIOS'ом в MSRC001_00[35:30] и, как несложно догадаться, написано там может быть всё, что угодно. В частности если BIOS не знает вашего процессора, то там часто оказываются куски разных названий самых разных процессоров. При этом всё более-менее работает, но вот называться процессор будет как-нибудь типа DuronFX4+ 600MHz.
    • +1
      Большое спасибо за уточнения! Как раз про то, что я не знал.

      P.S. А ещё у AMD есть забавная особенность: Brand String в их процессорах нет вообще.

      Я находил похожую информацию о том, что у некоторых VIA можно менять ещё и строку из нулевого листа, тоже через MSR'ы. И тем самым прикидываться GenuineIntel, AuthenticAMD и т.д.

      Фишка в том, что из одного и того же кристалла могут «выпекаться» совершенно разные CPU (в зависимости от того, сколько чего там работоспособно оказалось), да и коммерческое название процессора может меняться часто…

      По-моему, само введение всех этих строк было неудачной идеей как раз по этой причине.
  • 0
    Ещё одна фишка процессоров от AMD. Некоторые процессоры на ядре Bulldozer могут возвращать флаг AVX=1, но при этом флаги SSE42, SSE41 и SSSE3 равными 0, причём все эти технологии присутствуют. Зачем это сделано — не очень понятно. Но старые программы точно не смогут «обнаружить» технологии «занулёные» технологии.
    • +1
      Очень интересно. А можно поподробнее, откуда такая информация? Из официальной документации или пользователи обнаружили? Похоже на баг, такое обычно исправляют достаточно быстро обновлениями прошивки.
      • 0
        Я склонен считать, что это была бага процессора. В официальной доке ничего такого нет.

        К нам обратились клиенты, которые жаловались, что наше ПО медленно работает на их достаточно топовой машине. После процесса отладки было обнаружено, что большинство оптимизированных функций не работают. Стали смотреть на процедуру идентификации процессора и обнаружили, что CPUID выдаёт нулевые биты для «предыдущих» SSE технолигий. Самое интересное, что наше ПО находило бит AVX, но проверяло наличие всех битов AVX/SSE42/SSE41/SSSE3 для запуска AVX версии. Пришлось поправить код, и довольствоваться одним битом.
  • +1
    Дополню список софта для чтения CPUID: Sysinternals Coreinfo
    Утилита с довольно подробным выводом, умеющая читать также информацию из некоторых MSRов, связанных с поддержкой виртуализации. Например, на моей системе выдача следующая:

    c:\bin> Coreinfo.exe

    Coreinfo v3.31 — Dump information on system CPU and memory topology
    Copyright © 2008-2014 Mark Russinovich
    Sysinternals — www.sysinternals.com

    Intel® Core(TM) i5-4300U CPU @ 1.90GHz
    Intel64 Family 6 Model 69 Stepping 1, GenuineIntel
    Microcode signature: 00000017
    HTT * Hyperthreading enabled
    HYPERVISOR — Hypervisor is present
    VMX * Supports Intel hardware-assisted virtualization
    SVM — Supports AMD hardware-assisted virtualization
    X64 * Supports 64-bit mode

    SMX * Supports Intel trusted execution
    SKINIT — Supports AMD SKINIT

    NX * Supports no-execute page protection
    SMEP * Supports Supervisor Mode Execution Prevention
    SMAP — Supports Supervisor Mode Access Prevention
    PAGE1GB * Supports 1 GB large pages
    PAE * Supports > 32-bit physical addresses
    PAT * Supports Page Attribute Table
    PSE * Supports 4 MB pages
    PSE36 * Supports > 32-bit address 4 MB pages
    PGE * Supports global bit in page tables
    SS * Supports bus snooping for cache operations
    VME * Supports Virtual-8086 mode
    RDWRFSGSBASE * Supports direct GS/FS base access

    FPU * Implements i387 floating point instructions
    MMX * Supports MMX instruction set
    MMXEXT — Implements AMD MMX extensions
    3DNOW — Supports 3DNow! instructions
    3DNOWEXT — Supports 3DNow! extension instructions
    SSE * Supports Streaming SIMD Extensions
    SSE2 * Supports Streaming SIMD Extensions 2
    SSE3 * Supports Streaming SIMD Extensions 3
    SSSE3 * Supports Supplemental SIMD Extensions 3
    SSE4a — Supports Streaming SIMDR Extensions 4a
    SSE4.1 * Supports Streaming SIMD Extensions 4.1
    SSE4.2 * Supports Streaming SIMD Extensions 4.2

    AES * Supports AES extensions
    AVX * Supports AVX intruction extensions
    FMA * Supports FMA extensions using YMM state
    MSR * Implements RDMSR/WRMSR instructions
    MTRR * Supports Memory Type Range Registers
    XSAVE * Supports XSAVE/XRSTOR instructions
    OSXSAVE * Supports XSETBV/XGETBV instructions
    RDRAND * Supports RDRAND instruction
    RDSEED — Supports RDSEED instruction

    CMOV * Supports CMOVcc instruction
    CLFSH * Supports CLFLUSH instruction
    CX8 * Supports compare and exchange 8-byte instructions
    CX16 * Supports CMPXCHG16B instruction
    BMI1 * Supports bit manipulation extensions 1
    BMI2 * Supports bit manipulation extensions 2
    ADX — Supports ADCX/ADOX instructions
    DCA — Supports prefetch from memory-mapped device
    F16C * Supports half-precision instruction
    FXSR * Supports FXSAVE/FXSTOR instructions
    FFXSR — Supports optimized FXSAVE/FSRSTOR instruction
    MONITOR * Supports MONITOR and MWAIT instructions
    MOVBE * Supports MOVBE instruction
    ERMSB * Supports Enhanced REP MOVSB/STOSB
    PCLMULDQ * Supports PCLMULDQ instruction
    POPCNT * Supports POPCNT instruction
    LZCNT * Supports LZCNT instruction
    SEP * Supports fast system call instructions
    LAHF-SAHF * Supports LAHF/SAHF instructions in 64-bit mode
    HLE * Supports Hardware Lock Elision instructions
    RTM * Supports Restricted Transactional Memory instructions

    DE * Supports I/O breakpoints including CR4.DE
    DTES64 * Can write history of 64-bit branch addresses
    DS * Implements memory-resident debug buffer
    DS-CPL * Supports Debug Store feature with CPL
    PCID * Supports PCIDs and settable CR4.PCIDE
    INVPCID * Supports INVPCID instruction
    PDCM * Supports Performance Capabilities MSR
    RDTSCP * Supports RDTSCP instruction
    TSC * Supports RDTSC instruction
    TSC-DEADLINE * Local APIC supports one-shot deadline timer
    TSC-INVARIANT * TSC runs at constant rate
    xTPR * Supports disabling task priority messages

    EIST * Supports Enhanced Intel Speedstep
    ACPI * Implements MSR for power management
    TM * Implements thermal monitor circuitry
    TM2 * Implements Thermal Monitor 2 control
    APIC * Implements software-accessible local APIC
    x2APIC * Supports x2APIC

    CNXT-ID — L1 data cache mode adaptive or BIOS

    MCE * Supports Machine Check, INT18 and CR4.MCE
    MCA * Implements Machine Check Architecture
    PBE * Supports use of FERR#/PBE# pin

    PSN — Implements 96-bit processor serial number

    PREFETCHW * Supports PREFETCHW instruction

    Maximum implemented CPUID leaves: 0000000D (Basic), 80000008 (Extended).

    Logical to Physical Processor Map:
    **-- Physical Processor 0 (Hyperthreaded)
    --** Physical Processor 1 (Hyperthreaded)

    Logical Processor to Socket Map:
    **** Socket 0

    Logical Processor to NUMA Node Map:
    **** NUMA Node 0

    No NUMA nodes.

    Logical Processor to Cache Map:
    **-- Data Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64
    **-- Instruction Cache 0, Level 1, 32 KB, Assoc 8, LineSize 64
    **-- Unified Cache 0, Level 2, 256 KB, Assoc 8, LineSize 64
    **** Unified Cache 1, Level 3, 3 MB, Assoc 12, LineSize 64
    --** Data Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64
    --** Instruction Cache 1, Level 1, 32 KB, Assoc 8, LineSize 64
    --** Unified Cache 2, Level 2, 256 KB, Assoc 8, LineSize 64

    Logical Processor to Group Map:
    **** Group 0

    c:\bin> Coreinfo.exe -v

    Coreinfo v3.31 — Dump information on system CPU and memory topology
    Copyright © 2008-2014 Mark Russinovich
    Sysinternals — www.sysinternals.com

    Intel® Core(TM) i5-4300U CPU @ 1.90GHz
    Intel64 Family 6 Model 69 Stepping 1, GenuineIntel
    Microcode signature: 00000017
    HYPERVISOR — Hypervisor is present
    VMX * Supports Intel hardware-assisted virtualization
    EPT * Supports Intel extended page tables (SLAT)

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка