Дублирование функциональности для извлечения размера строки кэша с помощью cpuid

Я изучил документацию cpuid и обнаружил 2 различных задокументированных способа получения размера строки кэша:

  1. eax = 0x04, ecx = $cache_level

Таким образом, размер строки кэша в $cache_level будет храниться в EBX[11:0] битах.

  1. eax = 0x80000006

Таким образом, размер строки кэша будет храниться в ECX[7:0], а лист не зависит от уровня кэша.

ВОПРОС: В чем причина добавления информации о размере строки кэша в лист 0x80000006 и почему это не зависит от уровня кэша? У меня есть подозрение, что "правильный" способ получить размер строки кэша - eax = 0x04, ecx = $cache_level.


person St.Antario    schedule 20.09.2019    source источник


Ответы (1)


Intel и AMD (и VIA и...) — разные компании; и (к сожалению) нет никакого независимого от поставщика органа по стандартизации, ничто не принуждает к разумному сотрудничеству между поставщиками и ничто не мешает поставщикам устроить большой беспорядок в попытке выставить друг друга в плохом свете.

Когда AMD создала «CPUID, leaf 0x80000006», они поступили просто — предположили, что размер строки кеша одинаков для всех кешей, и поместили это в поле.

Однако (по крайней мере, теоретически) каждый отдельный кеш может иметь разный «размер строки»; поэтому, когда Intel создала «CPUID, leaf 0x00000004», они сделали так, чтобы (теоретически) каждый отдельный кеш мог сообщать о другом «размере строки».

Правильный путь состоит в том, чтобы иметь беспорядок, который упорядочивает беспорядок поставщика. Конкретно; для процессоров AMD вы можете использовать «CPUID, leaf 0x80000006», если можете; а для процессоров Intel (и процессоров VIA, я думаю) вы бы хотели использовать «CPUID, leaf 0x00000004», если можете; и для всех случаев, когда вы не можете (например, потому что ЦП слишком стар для поддержки метода поставщика), вы в конечном итоге столкнетесь с еще одним большим беспорядком (например, с использованием эвристики и/или с использованием «поставщик: семейство: модель: степпинг», чтобы найти информация в статической базе данных).

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

Примечание 1. Все вышеперечисленное не так сложно, если вас волнует только размер строки кэша; но чем больше информации вы хотите, тем хуже она становится (например, если вы также заботитесь о размере каждого кеша, вы должны ожидать примерно в 10 раз больше хлопот и 10-кратное бремя обслуживания).

Примечание 2. В идеале ОС должна предоставлять «предварительно обработанную информацию о ЦП»; так что его нужно обновлять только в одном месте, и чтобы обычному программному обеспечению не приходилось иметь дело с бессмысленными «различиями поставщиков», ошибками, отсутствующей информацией или объединенной информацией; и прямое использование инструкции CPUID было бы запрещено (по соображениям удобства, корректности и безопасности). К сожалению, ни одна существующая ОС не обеспечивает этого.

person Brendan    schedule 20.09.2019
comment
Таким образом, мы должны сначала определить поставщика ЦП (лист 0x00 предоставляет строковую информацию поставщика), а затем решить, какой лист использовать для запроса конкретной функции ЦП. - person St.Antario; 20.09.2019
comment
@St.Antario: Для размера строки кеша (и других параметров кеша) да - сначала обратитесь к поставщику. Для флагов функций ЦП это сложнее (в основном это зависит от того, кто его изобрел, а не от того, кто сделал настоящий ЦП). - person Brendan; 20.09.2019