Где документируется кеш памяти L1 процессоров Intel x86?
Я пытаюсь профилировать и оптимизировать алгоритмы, и я хотел бы понять специфическое влияние кэшей на различные процессоры. Для недавних процессоров Intel x86 (например, Q9300) очень сложно найти подробную информацию о структуре кеша. В частности, большинство веб-сайтов (в том числе Intel.com), что характеристики постпроцессора не содержат ссылок на кеш L1. Это потому, что кеш L1 не существует или эта информация по какой-то причине считается несущественной? Есть ли какие-либо статьи или дискуссии об устранении кеша L1?
[править]
После запуска различных тестов и диагностических программ (в основном те, которые обсуждались в ответах ниже), я пришел к выводу, что у моего Q9300, похоже, есть кеш данных 32K L1. Я до сих пор не нашел четкого объяснения, почему эта информация так трудно найти. Моя нынешняя теория работы заключается в том, что детали кэширования L1 теперь рассматриваются как коммерческие секреты Intel.
Ответы
Ответ 1
Практически невозможно найти спецификации кэшей Intel. Когда в прошлом году я преподавал класс по кэшам, я спросил друзей внутри Intel (в группе компиляторов), и они не смогли найти спецификации.
Но подождите!!! Jed, благослови его душу, сообщает нам, что в системах Linux вы можете сжать много информации из ядра:
grep . /sys/devices/system/cpu/cpu0/cache/index*/*
Это даст вам ассоциативность, размер набора и кучу другой информации (но не латентности).
Например, я узнал, что, хотя AMD рекламирует свой кеш L1 128K, мой компьютер AMD имеет разбитый кеш я и D по 64K каждый.
Два предложения, которые теперь в основном устарели благодаря Джеду:
-
AMD публикует гораздо больше информации о своих кешах, поэтому вы можете получить хотя бы некоторую информацию о современном кеше. Например, в прошлом году кэши AMD L1 доставили два слова за цикл (пик).
-
Инструмент с открытым исходным кодом valgrind
содержит в себе всевозможные модели кэша, и он бесценен для профилирования и понимание поведения кэша. Он поставляется с очень приятным инструментом визуализации kcachegrind
, который является частью KDE SDK.
Например: в третьем квартале 2008 года AMD K8/K10 В процессорах используются 64-байтовые строки кэша с кэш-памятью L1I/L1D на 64 КБ. L1D является 2-полосным ассоциативным и эксклюзивным с L2, с задержкой в 3 цикла. Кэш L2 имеет 16-канальную ассоциативность и латентность составляет около 12 циклов.
Процессоры семейства AMD Bulldozer используют разделенный L1 с 16-байтовым ассоциативным L1D для кластера (2 на ядро).
Процессоры Intel поддерживали L1 одинаково в течение длительного времени (от Pentium M до Haswell до Skylake и, предположительно, многих поколений после that): Split 32kB каждый я и D кэширует, причем L1D является 8-полосным ассоциативным. 64 байта, соответствующие размеру пакетной передачи DDR DRAM. Задержка загрузки составляет ~ 4 цикла.
Также см. x86 tag wiki для ссылок на более высокую производительность и микроархитектурные данные.
Ответ 2
Это руководство Intel: Справочное руководство по оптимизации архитектуры Intel® 64 и IA-32 имеет достойное обсуждение соображений кеша.
![enter image description here]()
Страница 46, раздел 2.2.5.1 Справочное руководство по оптимизации архитектур Intel® 64 и IA-32
Даже MicroSlop пробуждает потребность в дополнительных инструментах для мониторинга использования и производительности кэша и имеет функцию GetLogicalProcessorInformation() (... в то время как пылающие новые тропы при создании смехотворно длинных имен функций в процессе) Я думаю, что я буду кодировать.
ОБНОВЛЕНИЕ I: Hazwell увеличивает производительность загрузки кеша 2X, Inside the Tock; Архитектура Haswell
Если были какие-либо сомнения в том, насколько важно максимально использовать кеш, эту презентацию Клифф-клик, ранее принадлежавший Азулу, должен рассеять все сомнения. По его словам, "память - это новый диск!".
![Haswell’s URS (Unified Reservation Station)]()
ОБНОВЛЕНИЕ II: SkyLake значительно улучшил характеристики производительности кэша.
![Характеристики кэша SkyLake]()
Ответ 3
Вы смотрите на потребительские спецификации, а не на спецификации разработчика. Вот необходимая документация. Размеры кэша различаются в зависимости от подмоделей семейства процессоров, поэтому их, как правило, нет в руководствах по разработке IA-32, но вы легко можете найти их в NewEgg и т.д.
Отредактируйте: Более конкретно: главу 10 тома 3А (Руководство по системному программированию), главу 7 Справочного руководства по оптимизации и, возможно, что-то из руководства по кэшированию страниц TLB, хотя я предполагаю, что он находится далеко от L1 чем тебя волнует.
Ответ 4
Я еще несколько расследовал. В ETH Zurich есть группа, которая построила инструмент оценки производительности памяти, который мог бы получить информацию о размере по крайней мере (и, возможно, также ассоциативность) кэшей L1 и L2. Программа работает, используя экспериментальные эксперименты и измеряя полученную пропускную способность. Упрощенная версия была использована для популярного учебника Брайанта и О'Халларона.
Ответ 5
На этих платформах существуют кеши L1. Это почти наверняка останется истинным до тех пор, пока скорость шины памяти и фронтальной шины не превысит скорость процессора, что очень вероятно далеко.
В Windows вы можете использовать GetLogicalProcessorInformation для получения некоторого уровня информации о кеше (размер, размер строки, ассоциативность и т.д.). Ex-версия на Win7 даст еще больше данных, например, какие ядра разделяют этот кеш. CpuZ также предоставляет эту информацию.
Ответ 6
Locality of Reference оказывает большое влияние на производительность некоторых алгоритмов; Размер и скорость кеширования L1, L2 (и более поздних CPU L3), очевидно, играют большую роль в этом. Матричным умножением является один такой алгоритм.
Ответ 7
Intel Manual Vol. 2 определяет следующую формулу для вычисления размера кэша:
Этот размер кэша в байтах
= (Ways + 1) * (Partitions + 1) * (Line_Size + 1) * (Sets + 1)
= (EBX[31:22] + 1) * (EBX[21:12] + 1) * (EBX[11:0] + 1) * (ECX + 1)
Где Ways
, Partitions
, Line_Size
и Sets
запрашиваются с использованием cpuid
с eax
, установленным в 0x04
.
Предоставление объявления заголовочного файла
x86_cache_size.h
:
unsigned int get_cache_line_size(unsigned int cache_level);
Реализация выглядит следующим образом:
;1st argument - the cache level
get_cache_line_size:
push rbx
;set line number argument to be used with CPUID instruction
mov ecx, edi
;set cpuid initial value
mov eax, 0x04
cpuid
;cache line size
mov eax, ebx
and eax, 0x7ff
inc eax
;partitions
shr ebx, 12
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;ways of associativity
shr ebx, 10
mov edx, ebx
and edx, 0x1ff
inc edx
mul edx
;number of sets
inc ecx
mul ecx
pop rbx
ret
Который на моей машине работает следующим образом:
#include "x86_cache_size.h"
int main(void){
unsigned int L1_cache_size = get_cache_line_size(1);
unsigned int L2_cache_size = get_cache_line_size(2);
unsigned int L3_cache_size = get_cache_line_size(3);
//L1 size = 32768, L2 size = 262144, L3 size = 8388608
printf("L1 size = %u, L2 size = %u, L3 size = %u\n", L1_cache_size, L2_cache_size, L3_cache_size);
}