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

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

Ответ 1

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

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

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

Ответ 2

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

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


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

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

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

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

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

Ответ 3

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

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


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

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

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

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

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


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

На платформе x86 (которая использует страницы виртуальной памяти размером 4 КБ) 8-разрядные ассоциативные кэши L1 32 КБ распространены в современных разработках. Эти 8 тегов могут быть выбраны на основе младших 12 битов виртуального адреса, потому что эти биты одинаковы в виртуальных и физических адресах (они ниже смещения страницы для страниц размером 4 КБ). Этот скачок скорости для кэшей L1 работает, только если они достаточно малы и достаточно ассоциативны, чтобы индекс не зависел от результата TLB. 32киБ /64В линий /8-полосная ассоциативность = 64 (2 ^ 6) комплектов. Таким образом, младшие 6 бит адреса выбирают байты в строке, а следующие 6 бит индексируют набор из 8 тегов. Этот набор из 8 тегов выбирается параллельно с поиском TLB, поэтому теги можно параллельно проверять по битам выбора физической страницы результата TLB, чтобы определить, какой (если есть) из 8 способов кэширования хранить данные.

Создание большего кеша L1 означало бы, что ему нужно либо дождаться результата TLB, прежде чем он сможет даже начать извлекать теги и загружать их в параллельные компараторы, либо увеличить ассоциативность, чтобы сохранить log2 (sets) + log2 (line_size) & lt; = 12. (Чем больше ассоциативность, тем больше путей в наборе => меньше общих наборов = меньше индексных битов). Так, например кэш-память размером 64 КБ должна быть ассоциативной с 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). Это дает нам общий объем кэш-памяти L1 в 64 кбайт, статически разделенный на кэш-память кода и данных, за гораздо более дешевую (и, возможно, более низкую задержку), чем унифицированный кэш-память L1 размером 64 КБ с той же общей пропускной способностью. Поскольку между кодом и данными обычно очень мало совпадений, это большой выигрыш.

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

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


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

Большие кэши с меньшим трафиком также являются хорошим местом для размещения логики предварительной выборки. Аппаратная предварительная выборка обеспечивает хорошую производительность для таких вещей, как зацикливание массива, при этом каждому коду не требуются инструкции предварительной программной выборки. (Предварительная выборка SW была важна некоторое время, но предварительные выборки HW умнее, чем раньше, поэтому советы в Ульрихе Дреппере в остальном превосходны Что каждый программист должен знать о памяти устарел для многих случаев использования.)

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


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

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

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

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

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

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

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

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

Ответ 4

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

Ответ 5

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

Ответ 6

Другие ответы здесь дают конкретные и технические причины, почему 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 КиБ, 4-сторонние).


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

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

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

Ответ 7

логически, вопрос отвечает сам.

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

Зачем вам хранить ваши вещи на ленточном накопителе, если вы можете сохранить все это на жестком диске?