Почему размер кэша L1 меньше, чем размер кэша L2 в большинстве процессоров?

Почему размер кэша L1 меньше, чем размер кэша L2 в большинстве процессоров ?

7 ответов


для этого есть разные причины.

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

Так почему вообще существует кэш L2? Ну, кэш L1 обычно более эффективен и дорог для сборки, и он привязан к одному ядру. Это означает, что увеличение размера L1 на фиксированную величину будет иметь эту стоимость, умноженную на 4 в двойном ядерный процессор или 8 в четырехядерный. L2 обычно разделяется разными ядрами-в зависимости от архитектуры он может быть разделен между парой или всеми ядрами в процессоре, поэтому стоимость увеличения L2 была бы меньше, даже если бы цена L1 и L2 была одинаковой-что не так.


L1 очень тесно связан с ядром процессора и доступен при каждом доступе к памяти (очень часто). Таким образом, он должен возвращать данные очень быстро (обычно в течение такта). Задержка и пропускная способность (пропускная способность) являются критически важными для кэша данных L1. (например, задержка в четыре цикла и поддержка двух чтений и одной записи ядром процессора каждый такт). Для поддержки этой высокой пропускной способности требуется множество портов чтения/записи. Построение большого кэша с этими свойствами невозможно. Таким образом, дизайнеры держат его маленьким, например, 32KB в большинстве процессоров сегодня.

L2 доступен только при пропусках L1, поэтому доступы менее часты (обычно 1/20th из L1). Таким образом, L2 может иметь более высокую задержку (например, от 10 до 20 циклов) и иметь меньше портов. Это позволяет дизайнерам сделать его больше.


L1 и L2 играют очень разные роли. Если L1 будет больше, это увеличит задержку доступа L1, которая резко снизит производительность, потому что это сделает все зависимые нагрузки медленнее и сложнее скрыть для выполнения вне ордера. Размер L1 едва ли спорный.

Если мы удалили L2, L1 промахов придется перейти на следующий уровень, скажем памяти. Это означает, что большой доступ будет идти к памяти, что означает, что нам нужно больше пропускной способности памяти, что уже является узким местом. Таким образом, сохранение L2 вокруг благоприятно.

эксперты часто ссылаются на L1 как на фильтр задержки (поскольку это делает общий случай L1 быстрее) и L2 как фильтр полосы пропускания, поскольку он уменьшает использование полосы пропускания памяти.

Примечание: я предположил 2-уровень иерархия кэш в моем аргументе, чтобы сделать его проще. Во многих современных многоядерных чипах есть общий кэш L3 между всеми ядрами, в то время как каждое ядро имеет свой собственный L1 и, возможно, L2. В этих чипах общий кэш последнего уровня (L3) играет роль фильтра пропускной способности памяти. L2 играет роль фильтра ширины полосы частот на-обломока, т. е. оно уменьшает доступ к на-обломоку соедините и L3. Это позволяет конструкторам использовать соединение низк-ширины полосы частот как кольцо, и медленный одиночн-порт L3, который позволяет им сделать L3 более большим.

возможно, стоит упомянуть, что количество портов является очень важным моментом дизайна, потому что это влияет на то, сколько площади чипа потребляет кэш. Порты добавляют провода в кэш, который потребляет много площади чипа и мощности.


ответ@Aater объясняет некоторые из основ. Я добавлю еще несколько деталей + примеры реальной организации кэша на Intel Haswell и AMD Piledriver, с задержками и другими свойствами, а не только размером.

некоторые подробности о IvyBridge см. В разделе мой ответ на "как кэш может быть так быстро?", С некоторым обсуждением общей задержки использования нагрузки, включая время вычисления адреса, и ширины шин данных между различными уровнями кэш.


L1 должен быть очень fast (задержка и пропускная способность), даже если это означает ограниченную скорость попадания. L1d также должен поддерживать однобайтовые магазины почти на всех архитектурах, и (в некоторых конструкциях) unaligned доступа. Это затрудняет использование ECC (кодов исправления ошибок) для защиты данных, и на самом деле некоторые конструкции L1d (Intel) просто используют четность, с лучшим ECC только на внешних уровнях кэша (L2/L3), где ECC может сделайте на больших кусках для более низких накладных расходов.

невозможно создать один уровень кэша, который мог бы обеспечить низкую среднюю задержку запроса (усредненную по всем попаданиям и промахам) современного многоуровневый кэш. Поскольку современные системы имеют несколько очень голодных ядер, все они имеют соединение с одним и тем же относительно высоким DRAM с задержкой, это важно.

каждому ядру нужен свой собственный L1 для скорости, но, по крайней мере, последний уровень кэш обычно является общим, поэтому многопоточная программа, считывающая одни и те же данные из нескольких потоков, не должна идти в DRAM для каждого ядра. (И выступать в качестве опоры для данных, записанных одним ядром и прочитанных другим). для нормальной многоядерной системы требуется не менее двух уровней кэша, и является частью мотивации для более чем 2 уровней в текущих проектах. Современные многоядерные процессоры x86 имеют быстрый 2-уровневый кэш в каждом ядре и более медленный общий кэш всеми ядрами.

L1 hit-rate по-прежнему очень важен, поэтому кэш L1 не так мал / прост / быстр, как мог бы быть, потому что это уменьшило бы скорость попадания. Таким образом, достижение одинаковой общей производительности потребует более высоких уровней кэша, чтобы быть быстрее. Если более высокие уровни обрабатывают больше трафика, их задержка является большим компонентом средней задержки, и они чаще ограничивают пропускную способность (или нуждаются в более высокой пропускной способности).

высокая пропускная способность часто означает способный для регуляции множественных читает и пишет каждый цикл, т. е. множественные порты. Это занимает больше площади и мощность для той же емкости, что и кэш с более низкой пропускной способностью, так что это еще одна причина для L1 оставаться маленьким.


L1 также использует трюки скорости, которые не работали бы, если бы он был больше. т. е. большинство конструкций используют виртуально-индексированный, физически помеченный (VIPT) L1, но со всеми битами индекса, поступающими снизу смещения страницы, поэтому они ведут себя как PIPT (потому что низкие биты виртуального адреса такие же, как и в физическом адресе). Это позволяет избежать синонимы / омонимы (ложные попадания или те же данные, находящиеся в кэше дважды, и см. подробный ответ пола Клейтона на связанный вопрос), но все же позволяет части проверки попадания/промаха происходить параллельно с поиском TLB. Кэш VIVT не должен ждать TLB, но он должен быть недействительным при каждом изменении таблиц страниц.

на x86 (который использует Страницы виртуальной памяти 4kiB), 32kib 8-полосные ассоциативные кэши L1 распространены в современных дизайнах. 8 тегов могут быть извлечены на основе низких 12 бит виртуального адреса, потому что эти биты одинаковы в виртуальных и физических адресах (они ниже смещения страницы для страниц 4kiB). Этот speed-hack для кэшей L1 работает только в том случае, если они достаточно малы и ассоциативны, чтобы индекс не зависел от результата TLB. 32kiB / 64B lines / 8-way associativity = 64 (2^6) множества. Так, самые низкие 6 биты адреса выберите байты в строке, а следующие 6 бит индекс набор из 8 теги. Этот набор из 8 тегов извлекается параллельно с поиском TLB, поэтому теги могут быть проверены параллельно с битами выбора физической страницы результата TLB, чтобы определить, какой (если таковой имеется) из 8 способов хранения данных кэша.

создание большего кэша L1 означало бы, что он должен был либо ждать результата TLB, прежде чем он мог бы даже начать получать теги и загружать их в параллельные компараторы, или ему пришлось бы увеличить ассоциативность, чтобы сохранить log2(sets) + log2 (line_size) меньше общих наборов = меньше индексных битов). Так, например, кэш 64kiB должен быть 16-полосным ассоциативным: все еще 64 набора, но каждый набор имеет в два раза больше способов. Это делает увеличение размера L1 за пределами текущего размера непомерно дорогим с точки зрения мощности и, вероятно, даже задержки.

тратить больше энергии бюджет на логике кэша L1D оставит меньше энергии для выполнения вне заказа, декодирования и, конечно же, кэша L2 и так далее. Получение всего ядра для работы на 4 ГГц и поддержания ~4 инструкций за часы (на высоком ILP-коде) без плавления требует сбалансированного дизайна. См. эту статью: Современные Микропроцессоры: 90-Минутный Гид!.

чем больше кэш, тем больше вы теряете, смывая его, поэтому большой кэш VIVT L1 будет хуже, чем текущий VIPT-который-работает-как-PIPT. И более крупный, но с более высокой задержкой L1D, вероятно, также будет хуже.

согласно @PaulClayton, Кеши L1 часто приносят все сведения в наборе параллельно тегам, поэтому он готов к выбору после обнаружения правильного тега. Стоимость мощности для этого масштабируется с ассоциативностью, поэтому большой высокоассоциативный L1 был бы очень плох для использования энергии, а также для области (и латентности). (Сравненный для L2 и L3 это не будет большой площадью, но физическая близость важна для задержки. Задержки распространения скорости света имеют значение, когда тактовые циклы составляют 1/4 наносекунды.)

более медленные кэши (например, L3) могут работать при более низком напряжении / тактовой частоте, чтобы сделать меньше тепла. Они могут даже использовать различные расположения транзисторов для каждой ячейки памяти, чтобы сделать память более оптимизированной для питания, чем для высокой скорости.

есть много причин, связанных с использованием энергии для многоуровневые тайники. Мощность / тепло является одним из самых важных ограничений в современном дизайне процессора, потому что охлаждение крошечного чипа трудно. Все является компромиссом между скоростью и мощностью (и/или областью смерти). Кроме того, многие процессоры питаются от батарей или находятся в дата-центрах, которые нуждаются в дополнительном охлаждении.


L1 почти всегда разделен на отдельные кэши инструкций и данных. вместо дополнительного порта чтения в унифицированном L1 для поддержки выборки кода мы можем иметь отдельный кэш L1I привязан к отдельному I-TLB. (Современные процессоры часто имеют L2-TLB, который является вторым уровнем кэша для переводов, разделяемых L1 I-TLB и D-TLB, а не TLB, используемым обычным кэшем L2). Это дает нам 64kib всего кэша L1, статически разбитого на кэши кода и данных, намного дешевле (и, вероятно, с меньшей задержкой), чем унифицированный кэш monster 64k L1 с той же общей пропускной способностью. Поскольку обычно очень мало перекрытий между кодом и данными, это большой выиграть.

L1I можно поместить физически близко к логике код-выборки, пока L1D может быть физически близко к блокам нагрузки/магазина. Задержки в линии передачи скорости света имеют большое значение, когда тактовый цикл длится всего 1/3 наносекунды. Маршрутизация проводки также имеет большое значение: например Intel Broadwell имеет 13 слоев меди над кремнием.

Split L1 очень помогает со скоростью, но unified L2-лучший выбор. Некоторые заказы очень небольшой код, но много данных. Имеет смысл объединить кэши более высокого уровня для адаптации к различным рабочим нагрузкам вместо статического разбиения на код и данные. (например, почти все L2 будут кэшировать данные, а не код, при запуске большой матрицы умножать, против наличия большого количества кода при запуске раздутой программы C++ или даже эффективной реализации сложного алгоритма (например, запуск gcc)). Код может быть скопирован как данные, а не только загружен с диска в памяти с DMA.


кэши также нуждаются в логике для отслеживания выдающихся промахов (поскольку выполнение вне порядка означает, что новые запросы могут продолжать генерироваться до разрешения первого промаха). Наличие многих промахов означает, что вы перекрываете задержку промахов, достигая более высокой пропускной способности. Дублирование логики и / или статическое разделение между кодом и данными в L2 не было бы хорошим.

больше меньше-трафик кэши также хорошее место, чтобы положить предварительная логика. Аппаратная предварительная выборка обеспечивает хорошую производительность для таких вещей, как цикл по массиву без каждого фрагмента кода, нуждающегося в инструкциях по программной предварительной выборке. (SW prefetch был важен некоторое время, но HW prefetchers умнее, чем раньше, так что совет в Ульрих Drepper в остальном отличное Что Каждый Программист Должен Знать О Памяти!--13--> устарел для многих случаев использования.)

низким трафиком выше схрона уровне позвольте задержке делать умные вещи, такие как использование адаптивная политика замены вместо обычного LRU. Intel IvyBridge и более поздние процессоры делают это, чтобы противостоять шаблонам доступа, которые не получают кэш-хитов для рабочего набора, слишком большого, чтобы поместиться в кеш. (например, цикл над некоторыми данными в одном и том же направлении дважды означает, что он, вероятно, выселяется непосредственно перед его повторным использованием.)


реальный пример: Intel Хасвелл!--13-->. Источники:анализ микроархитектуры Дэвида Кантера и результаты тестирования Agner Fog (microarch pdf). См. также руководства по оптимизации Intel (ссылки в x86 тег wiki).

кроме того, я написал отдельный ответ на: какой метод отображения кэша используется в процессоре intel core i7?

современные проекты Intel используют большой включительный кэш L3, общий для всех ядер как подпорка для кэш-когерентности движения. Он физически распределен между ядрами, с 2048 наборами * 16-way (2MiB) на ядро (с адаптивная политика замены в IvyBridge и позже).

нижние уровни кэша на ядро.

  • L1: per-core 32kiB каждая инструкция и данные (split), 8-полосная ассоциативная. задержка = 4 цикла. По крайней мере 2 порта чтения + 1 порт записи. ( возможно, даже больше портов для обрабатывать трафик между L1 и L2, или, возможно, получение строки кэша из L2 конфликтует с выходом из магазина.) Может отслеживать 10 выдающихся пропусков кэша (10 буферов заполнения).
  • L2: унифицированный per-core 256kiB, 8-полосный ассоциативный. задержка = 11 или 12 циклов. Скорость чтения: 64 байт / цикл. Основная логика prefetching prefetches в L2. Может отслеживать 16 выдающихся промахов. Смогите поставить 64B в цикл к L1I или L1D. Фактическое количество портов неизвестный.
  • L3: унифицированный, общий (всеми ядрами) 8MiB (для четырехъядерного i7). Включительно (из всех кэшей L2 и L1 на ядро). 12 или 16 способ ассоциативный. задержка = 34 цикла. Действует как резервная точка для согласованности кэша, поэтому измененные общие данные не должны выходить в основную память и обратно.

еще один реальный пример: AMD Piledriver: (например, процессоры Opteron и desktop FX.) Размер кэш-строки по-прежнему 64B, как Intel и AMD, используется уже несколько лет. Текст в основном скопирован из микроархива pdf Агнера Фога,с дополнительной информацией из некоторых слайдов, которые я нашел, и более подробную информацию о записи через L1 + 4K записи объединения кэша в блоге Агнера С комментарий, что только L1 является WT, а не L2.

  • L1I: 64 КБ, 2-полосная, разделяемая между парой ядер (версия AMD SMD имеет больше статического разбиения, чем Гиперпотоки, и они называют каждый из них ядром. Каждая пара разделяет блок vector / FPU и другие ресурсы конвейера.)
  • L1D: 16 КБ, 4 пути, в ядр. задержка = 3-4 c. (Обратите внимание, что все 12 бит ниже смещения страницы по-прежнему используются для индекса, поэтому работает обычный трюк VIPT.) (пропускная способность: две операции в сутки, до одного из них-магазин). Политика = Запись Через С записи 4К-объединение кэш.
  • L2: 2 МБ, 16-полосная, общая между двумя ядрами. задержка = 20 часов. Прочитайте объем 1 в 4 часа. Пропускная способность записи 1 на 12 часов.
  • L3: 0-8 MB, 64-way, общий доступ между всеми ядрами. задержка = 87 часов. Прочитанный объем 1 в 15 часов. Напишите пропускную способность 1 в 21 часы

Agner Fog сообщает, что с обоими ядрами активной пары пропускная способность L1 ниже, чем когда другая половина пары бездействует. Неизвестно, что происходит, так как кэши L1 должны быть отдельными для каждого ядра.


Я думаю, что основная причина для этого ist, что L1-Cache быстрее, и поэтому он дороже.


для тех, кто интересуется этим типом вопросов, мой университет рекомендует Компьютерная Архитектура: Количественный Подход и организация и дизайн компьютера: аппаратно-программный интерфейс. Конечно, если у вас нет времени для этого, краткий обзор доступен на Википедия.


другие ответы здесь дают конкретные и технические причины, почему L1 и L2 имеют размер, как они есть, и хотя многие из них мотивируют соображения для конкретных архитектур, они на самом деле не нужны: основное архитектурное давление, приводящее к увеличению (частных) размеров кэша, когда вы удаляетесь от ядра, довольно универсально и совпадает с рассуждениями для нескольких кэшей в первую очередь.

три основных факта:

  1. в доступ к памяти для большинства приложений демонстрирует высокую степень временной локальности с неравномерным распределением.
  2. через большое разнообразие процесса и конструкций, размер кэша и скорость кэша (задержка и пропускная способность) могут быть обменены друг против друга1.
  3. каждый отдельный уровень кэша включает в себя инкрементный дизайн и стоимость производительности.

таким образом, на базовом уровне вы можете сказать, что размер кэша вдвое больше, но штраф за задержку 1.4 по сравнению с меньшим кэшем.

таким образом, это становится проблемой оптимизации: сколько кэшей у вас должно быть и насколько они должны быть большими? Если бы доступ к памяти был полностью однородным в пределах рабочего размера набора, вы, вероятно, получили бы один довольно большой кэш или вообще не кэш. Однако доступ сильно неоднороден, поэтому небольшой и быстрый кэш может захватывать большое количество обращений, непропорциональных его размеру.

Если бы Факт 2 не существовал, вы бы просто создайте очень большой, очень быстрый кэш L1 в пределах других ограничений вашего чипа и не нуждайтесь в других уровнях кэша.

Если бы Факт 3 не существовал, у вас было бы огромное количество мелкозернистых "кэшей", быстрее и меньше в центре, и медленнее и больше снаружи, или, возможно, один кэш с переменным временем доступа: быстрее для частей, ближайших к ядру. На практике правило 3 означает, что каждый уровень кэша имеет дополнительную стоимость, поэтому вы обычно получаете несколько квантованных уровни кэша2.

Другие Ограничения

Это дает базовую структуру для понимания количества кэша и решений по размеру кэша, но есть и вторичные факторы. Например, Intel x86 имеет размеры страниц 4K, а их кэш L1 использует VIPT архитектура. VIPT означает, что размер кэша, разделенный на количество способов, не может быть больше3 чем 4 Кб. Таким образом, 8-полосный кэш L1, используемый на полудюжине проектов Intel может быть не более 4 КБ * 8 = 32 Кб. Вероятно, не случайно, что это именно размер кэша L1 на этих проектах! Если бы не это ограничение, вполне возможно, вы бы увидели меньшую ассоциативность и/или большие кэши L1 (например, 64 KiB, 4-way).


1 конечно, есть и другие факторы, участвующие в компромиссе, такие как площадь и мощность, но, удерживая эти факторы постоянными, применяется компромисс размер-скорость, и даже если он не проводится константа основное поведение то же самое.

2 в дополнение к этому давлению существует преимущество планирования для кэшей с известной задержкой, как и большинство проектов L1: и вне порядка планировщик может оптимистично отправлять операции, которые зависят от нагрузки памяти на цикл, который кэш L1 вернет, считывая результат с сети обхода. Это уменьшает разногласия и, возможно, сбивает цикл задержки с критического пути. Это оказывает некоторое давление на внутренний кэш уровень, чтобы иметь равномерную / предсказуемую задержку и, вероятно, приводит к меньшему количеству уровней кэша.

3 в принципе, вы можете использовать кэши VIPT без этого ограничения, но только требуя поддержки ОС (например, раскраски страниц) или с другими ограничениями. X86 arch этого не сделал и, вероятно, не может начать сейчас.


логически вопрос отвечает сам на себя.

Если бы L1 был больше L2 (в сочетании), то не было бы необходимости в кэше L2.

Почему вы храните свои вещи на ленточном накопителе, если вы можете хранить все это на HDD ?