Лекция 4 (2012-11-03)

Устройство памяти

Сегодняшняя лекция будет про устройство памяти и взаимодействие процессора с ней. Начиная с видов яччеек памяти, какая бывает память.

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

Память можно классифицировать следующим образом:

В дальнейшем будем преимущественно рассматривать энергозависимую память, а именно два вида -- SRAM и DRAM. Static random Access Memory, Dynamic Random access memory.

Начнем с SRAM, потому что она нам по большому счету знакома. Если намдать триггер с некоторыми ограничениями.

Так получилось, что сейчас все устроено на транзисторах. npn, pnp.

general_view.jpg

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

Вход и выход объединены. чтобы записать сначала поднимаем и опускаем отрицание BL, а потом поднимаем write enable. Практически как в защёлке по фронту, но объединили вход и выход.

В чем плюшки статической памяти

SRAM просто кусок логики, точно так же как и триггер. Хотя это довольно удобный и быстрый способ хранения данных, он имеет недостатки. Долго рисовали, но и в чипе это не так просто -- шесть транзисторов сделать, да еще и их соединить. статическая память считается дорогой, размещать её сложнее, она занимает больше места поэтому её нельзя делать много. Есть варианты статической памяти с 1-3-4-8-10 транзисторами различными. Увелечиние количества транзисторов для стабилизации питания, потому что когда вы открываете гейты происходит достаточно сильный скачок питания. Уменьшение тоже имеет ряд недостатков -- вы начинаете терять преимущества, которые предоставляет статическая память.

Есть более экономичные способы хранения данных. Например, динамическая память.

Динамическая память это конденсатор, который гейтится с транзистором.

memmory_cell.jpg

Штамповать такие ячейки память значительно проще. Динамическая память всем хороша, но жутко неудобна, потому что для хранения использует просто разность потенциалов на конденсаторе. Если открываете гейт и течет ток -- есть что-то, не течёт -- нет. Если конденсатор слишком маленький, то ток он отдает недолго, небыстро, и вообще отдает его очень мало. В связи с этим для использования DRAM надо использовать усилители, после многократного чтения нужно обновлять ее состояние, кроме того конденсаторы маленькой емкости имеют свойство разряжать со временем и к ячейкам DRAM надо применять такую операцию как рефреш -- обновление. Чтение DRAM также получается небыстрой операцией.

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

Динамическая память организуется довольно определенным образом. вы наверно слышали про DDR SDRAM с какой нибудь циферкой -- 1,2,3,4. S - synchronous, double data rate.

Как устроена SDRAM? Фактически оно организовано примерно так, как рассматривалось ранее -- мультиплексор и демультиплексор, только чуть сложнее. Современные чипы это уже несколько гигабит, поэтому организована она в виде набора двумерных массивов. В Row подается адрес. Массив обычно примерно квадратный. На пересечении стеик изображены ячейки памяти DRAM.

memory_scheme.jpg

Идея в следующем. В виду того, что городить селектор и мультиплексор из 30 бит адреса в миллиард ячеек это плохая затея, используют такую конструкцию, снижающую разрядность адреса в два раза, и выбор строки и столбца происходит раздельно. Мы экономим на интерфейсе чипа и всего модуля памяти, мы экономим на размере мультиплексоров и демультиплексоров. Работает она следующим образом. Делается Row Adress Select.

Есть Addr, RAS (Raw Adress Strobe)и CAS(Column Adress Strobe). На спадающем фронте RAS считываем CAS и защелкивается как адрес, потом мы мигаем CAS и выбираем столбец, а дальше мы используем ещё один строб, из которого уже получаем данные свои.

Дальше для них последовал ряд оптимизаций, в частности Past Page Switch. Если мы читаем несколько столбцов, мы можем не делать заново выбор строки -- Fast Page Mode (FPM) DRAM. EDO DRAM умела подавать следующую команду пока ещё идут данные. Схема.

ras_cas_addr_do_data.jpg

Ras 2 CAS latency, CAS latency, precharge, command rate, actively precharge-- характеристики чипа.

Следующим важным этапом было Burst EDO RAM. Позволяла получать данные бёрстами -- происходил автоинкремент адреса и получали до 4 блоков данных. Почему блоков? Ширина этого набор сигналов она в принципе 4-8-16 бит, чаще всего 4 или 8. Таких матриц не одна, а несколько и читаете вы с них фактически параллельно.

Дальше появилась SDRAM, которая начала нормально тактироваться. Асинхронный DRAM в чем проблема была -- рефреш был асинхронный. А у синхронной DRAM команды рефреша шли общим потоком.

СDRAM. Частота от 100 до 200 мегагерц, то есть можно было 8-1600 мегабайт, хотя реально на 200 мегагерц не раскачивали, обычно 100-133.

Дальше появилось то самое DDR. Идея в том, что у нас появляется некий буфер. А дальше вы отдаете данные по двум фронтам.

В DDR2 удвоили количество бит которые в буффере и удвоили частоту. В DDR3 ещё тоже самое -- буффер на 8 бит и отдают на увеличенной частоте по двум фронтам.

Частота работы конструкции за 10-15 лет не сильно поменялась -- там все равно конденсаторы и вместо того, чтобы его разогнать его просто уменьшают -- мы сохраняем частотоу но запихиваем большее количество ячеек, а с больше ячеек мы можем отдавать их больше за раз за счет параллелизма.

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

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

Так устроен интерфейс самого чипа DRAM. В модуле DRAM этих чипов находитс несколько. Ширина интерфейса 64 бита или 72. На модуле может быть несколько так называемых ранков, которые могут выбираться сигналом чипселект. Может быть один ранк, может больше. n ranks, m chips, each of them w bits wide. Magic formula w*m = n*64. идея в том, что у вас есть н ранков, каждый из которых может отдавать 64 бита, таким образом они собраны в м чипов, каждый из которых отдает по в битов. Сермяжная суть этой формулы в том, что она позволяет понять насколько вы можете вообще ра??шивать доступ памяти применительно к конкретным модулям. w = 4/8/16. 4 for ECC (9 чипов, 8 данные, в 9 error correction code).

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

По поводу DDR3. Начиная с него сняли ограничения на сброс. Тяжесть DDR2 была в том,что изначально синхроноус DRAM предполагает что все сигналы призжають более менее одновременно. На 100 мгц разбегание дорожек ещё можно выдержать, оно окло милимметра. На DDR2 стало понятно, что количество доржек растет, а требования к разводке все также усугубляются. Разбегание доржки становится дефакто в 2 раза меньше. В DDR3 сняли ограничение и сихронизация ушла частично на следующий уровень поэтому в том числе там были более высокие задержки, но разводить стало челоевечней.

JEDEC

На сегодня уже сотни гигабайт в секунду.

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

Кэширование L1, L2, L3.

L1 идет на ядро, имеет размер сейчас порядка 32 килобайт, 4-8 ассоциативны. Все ли помнят что такое ассоциативность? Кэшировать отдельный байты очень плохо, поэтому в кэше хранятся обычно строки по 32/64 байта. За счет того, что они выровнены -- младшие 6 бит адреса вам говорят где брать ячейку в строке. Но надо ещё найти строку. Можно было бы искать по всем оставшимся битам адреса (назвав их тег) и за одно сравнение быстренько находить нужную линейку кэша. Но возникает загвоздка -- параллельное сравнение требует количество транзисторов и проводов очень большое при росте уровня кэша. Развести 20 000 дорожек и разместить 20000 транзисторов это логически не очень простая задача, которая очень плохо ршается. Это будет полная ассоциативность.

Есть подход с точностью до противоположного. Проверяем совпали биты или нет, если не совпали загружаем из памяти. Эффективность такого решения не очень высокая, потому что вы начинаете выкидывать строки,которые отстоят на 2^(s+6) байт, что может быть плохо с точки зренияя кэшмиссов если атомы наших данных толще. Поэтому строки объединяются в блоки по 4-8. Таким образом будут сначала индексироваться блок, а потом в нем полноассоциативно искать нужный адрес, но делать это уже среди 4-8 строк.

4-ассоциативного кэша достаточно, чтобы сгладить негативные эффекты алиасинга и уменшить кэш миссы в 2.5-3 раза. В L1 виртуальная адресация. L2 кэш 1-4 мегабайта, ассоциативность 4-16, физическая адресация. с виртуальной адресацией при смене контекста кэш теряется. В L2 может влезать несколько конетксов, к тому же он медленный -- 10-20 тактов и это вполне сглаживает преобразование виртуального адреса в физический. L2 кэш шарится между небольшим количеством ядер, например двумя. L2 это просто большой кэш, но все так же у ядра.

L3 сейчас уже у всех. В x86 появился первым у амд, до этого был у поверов и спарков. У итаниумов он был одним из способв компенсации недостатков архитектуры -- ядер было всего ничего, но зато они толстые. L3 per chip.

Инфраструктура кэшей позволяет сглаживать доступ в память.

Переходим к адресации.

В подавляющем большинстве современных архитектру используется странично-сегоментная адресация памяти.

virt_addr_to_phys.jpg

Есть виртуал адрес и физикал адрес. Отображение между ними для организации всех этих современных плюшек -- многопроцессорность, защищенный режим, должен выполняться, и он выполняется но снекотрой гранулярностью. Размер гранулы -- страница. Кроме того, это отображение выполняется аппаратно. Занимается этим блок memory management unit. Ему задется некоторая информация о том, что у нас есть неокторое отображение и дальше он может по этой информации выполнять преобразование. Как оно происходит.

Есть виртуальный адрес, он разбиивается на две части -- адрес внутри страницы и индекс. И есть некая таблица в памяти,на которую указывает некоторый внутренний регистр. Смотрим в ней по индексу, получили указатель на физический адрес. Размер этой таблицы будет экспонентой от количества бит. Такая простая схема используется только для очень больших страниц -- 4 мегабайта, например, тогда для 32-бит адресов там будет 10 бит.Но далеко не всегда удобно оперировать такими страницами. Обычно используются таблицы 4 килобайта. Тогда для 32 разрядной архитектуры на индекс остается 20 бит. Тогда вы разбиваете адрес на несколько частей и делаете косвенную адресацию. Работает так -- вы берете старшие несколько бит адреса, индесируете таблицу первымнабором битов, там адрес следующей таблицы, которая индексируется следующим набором битов и так далее, и на 4ой итерации вы находите префикс который так долго ждали. Все хорошо, но получаются 4 последовательных операций.

Сейчас используется 4 уровня, ищется по 34 битам. размеры наборов битов по 9 бит. Каждая таблица 512 записей, общей мощностью 4 килобайта.

4 последовательных поиска -- штука не очень хорошая. Чтобы её сгладить есть такая штука как тлб, которая кэширует результаты этих преобразований. Она тоже многоуровневая, как кэши. по крайней мере у интела она полносвязная. Там 128 или 256 записей, и разводится она очень тяжко, потому что там реально нужна полная ассоциативность. Есть тлб 2 уровня, у которой уже есть какая-то ассоцитивность 4 или 8. Длина строки 32 бита, там напиханы индексы и флаги.

Пае увеличло размер записи в 32 бит до 64. когда это появилось это был 96, когда появился пентиум про. Казалось, выгоды никаккой нету. 20 бит чудесно укладывались в три уровня. Пае добавил 4 уровень и сделал размеры записей в два раза больше. Тогда 8-64 гб памяти на серверах было не очень распространено на x86.

Вообще говоря, различные регионы памяти могут использоваться различными способами. Иногда они отображаются на чипы DRAM как есть, а иногда нет, а отображаться на памятьвидео устройства, или PCI експресс устройства, или просто как то мапится могут. Все эти особенности конфигурируются через memory type range reisters, там же конфигурируется способ использования данного региона. Например, можно сккзать, что операции записи можно кэшировать и послыать более оптимальным способом (выровненными лингецками по 64 байта). В основном нужен для PCI експресс устройств чтобы указать особенности семантики -- можно ли кэшировать чтение, выполнять чтение без побочных эффектов, или противоположную штуку, что кэшировать операции с этой памятью вообще нельзя, например если туда выведены какие-то условные ио порты(хотя они вообще отдельно) ну или какому-то устройству надо сразу и точно получать те операции.

Кэши бывают двух типов write-through и write-back. Это режи мработы кэша. Сквозная запись -- у вас есть линейка в кэше, вы ее обновляете -- в память сразу идет запись. райт бэк просто помечает линейку, что он грязная, и при выбрасывании из кэша она записывается. Райт бэк лучше с точки зрения производительности но порождает доп проблемы с когерентностью. Чтобы их решать есть механизм MESI Modified Exclusive Shares Invariant -- стейт машина которая определяет как происходит переход между этими 4 состояниями кэша -- модифайд, эксклюзив, шаред, инвэлид. И действия -- лоад, стор и ещё два. Если разрисовывать там грустная таблица переходов. Идея в том, что это прописывается и жизнь сразу становится проще и понятней. Начиная с нехалемов используется MESIF, когда необходима полная свзяность между кэшами -- если модифицируете шаред ячейку, то ее надо сразу писать, а Forward говорит что она уже модифицирована и не вызывает дополнительных пересылок. Request for ownership надо делать если для шаред вы хотите модифицировать. Рфо станет инвэлид посл еэтого вы ее делаете модифайд.

DMA --direct memory access, когда устройства могут работать с памятью напрямую, как ядра. Будем говорить дальше, когда говорить про переферию.

IOMMU. как можно было заметить мму -- чатсь процессора. А переферийные устройства ею нея влются и ничего не знают про отображение виртуальных адресов в физические. Поэтому для устройств не работают все механизмы защиты памяти. Берете файрвайр и пишете/читаете в любое место памяти. И ничего с этим не сделаешь. помимо файрвайр такими особенностями обладает PCI Express. Хотя сейчас наконец-то в x86 появился иомму, когда у вас есть дополнительный чип перед мемори контроллером который занимается отображением тех адресов, которые использует железка в адреса физической памяти. У интела это называется очень красиво VTd, но в реальности это все попытка реализовать IOMMU. Реалищуется как и мму,только конфигурировать его сложнее потому тчо находится он дальше от процессора.

e820 эт оназвание такой микросхемы, было. Сейчас это просто некий интерфейс который позволяет конфигурировать те регионы которые доступны/или недоступны.

Full buffer. Это способ переложить часть работы мемори контроллера на модуль памяти. он фактически сам выдает команды чтения записи и выдает уже просто данные. таким образом вы забарываете проблему что вы не можете повесить много модулей памяти на одну шину. DDR2 240 дорожек. 480 ног это дофига.

У современных x86 их всего чуть больше 2000.

http://upload.wikimedia.org/wikipedia/commons/8/8e/MultiChipModule.JPG У IBM z10 было 8765 ног, они собиралось в MCM по 5 + 2 storage контроллера, и ящики чипов памяти. стоило это 10 миллионов долларов, было совместимо с систем 360 и было майнфреймом. Вот это реальная архитектура не то что инетл, который уже дропнул реальный режим, который всего-то 30 лет назад появился.

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

COntent Addressable Memory. cam и tcam часто используются в чипах роутеров, когда у вас стоит задача по IP адресу установить кому посылать пакет. Т она вообще от троичности. -- расширение когда у вас надо длеать поиск по маске -- помимо ключа ещё указывается маска по которой надо сравнивать. dest ip, prefix+mask. То есть не столько для поиска сколько уже для применеия правил. Соответственно отличается оно тем что сверяютс ятольк те Destination IP биты, у которых маска единица. У маршрутизаторов приор иттет имеют те префиксы, которые длиннее. В случае с памятью приоритет имеют те записи,к оторые лежат раньше в памяти соответственно роутеры просто упорядочивают эти префиксы по длине.

LecturesCMC/ComputerArchitecture2012/Conspects/03 (последним исправлял пользователь Allena 2012-12-21 02:26:26)