mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 09:10:10 +00:00
Добавление конспектов лекций
This commit is contained in:
26
Lectures/01. Introduce.md
Normal file
26
Lectures/01. Introduce.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Лекция 1. Вводная
|
||||
|
||||
В этой лекции вы познакомились с кругом вопросов, которым занимается дисциплина «Архитектура процессорных систем», посмотрели небольшой исторический очерк, обобщенный план дисциплины и разобрали несколько основных определений (которые надо знать!), такие как:
|
||||
|
||||
> **Процессор** — программно-управляемое устройство, выполненное на одной интегральной схеме и предназначенное для цифровой обработки информации и управления этим процессом.
|
||||
> **Архитектура** — абстрактная модель функциональных возможностей процессора (средства, которыми может пользоваться программист).
|
||||
> **Микроархитектура** — физическая модель процессора, которая устанавливает состав, порядок и принципы взаимодействия его основных функциональных частей (структурная организация).
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](http://www.youtube.com/watch?v=Xtc7NkQUGpE) на видеозапись лекции
|
||||
2. Отличный текст про абстракцию, базовые принципы управления сложностью и системы счисления, если вдруг ты забыл как это **[Харрис и Харрис**. *Цифровая схемотехника и архитектура компьютера —* параграф 1.2]
|
||||
3. Разбор понятий архитектуры и микроархитектуры, в том числе согласно международному стандарту [**Орлов и Цилькер**. *Организация ЭВМ и систем* — Глава 1. параграф 'Определение понятий «организация» и «архитектура»']
|
||||
4. Общее представление о дисциплине и несколько основных определений, которые необходимо знать и понимать [**Кафедра ВТ**. *Микропроцессорные средства и системы* — Лекция 1.1]
|
||||
5. [Здесь](https://studfiles.net/preview/2523586/page:2/) классификация процессоров по выполняемым функциям, приведенная на лекции, другая классификация с пояснениями есть в сборнике лекций [**Кафедра ВТ**. *Микропроцессорные средства и системы* — Лекция 1.1]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Более подробный исторический обзор развития процессоров [**Орлов и Цилькер**. *Организация ЭВМ и систем* — Глава 1. параграф 'Эволюция средств автоматизации вычислений']
|
||||
2. Статистическая информация о положении дел на рынке полупроводников, можно посмотреть и почитать по [ссылочке](https://www.tadviser.ru/index.php/Статья:Полупроводники_(мировой_рынок))
|
||||
|
||||
## Популярные материалы
|
||||
|
||||
1. Пример проектирования сумматора (элемент процессора выполняющий операцию сложения двоичных чисел) не на транзисторах, а прямо в компьютерной игре на ветряных мельницах и сточных водах, по [ссылочке](https://dtf.ru/games/59663-igrok-sozdal-v-cities-skylines-summator-rabotayushchiy-na-vetryanyh-melnicah-i-stochnyh-vodah)
|
||||
2. Восьмибитный процессор сделанный [прямо в Minecraft](https://www.youtube.com/watch?v=ziv8SXfMbkk)
|
||||
3. Популярная [статья](https://thecode.media/intel_inside/) о том, как производят процессоры
|
35
Lectures/02. Instruments.md
Normal file
35
Lectures/02. Instruments.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# Лекция 2. Основные концепции и инструменты
|
||||
|
||||

|
||||
|
||||
Для каких бы специализированных задач не разрабатывались процессоры, структурно любой их них состоит из 4 основных блоков: ***память,*** для хранения данных и команд, ***операционное устройство***, для выполнения различных операций над данными, ***блока интерфейсной логики***, для сопряжения ядра процессора с внешним миром, и ***устройства управления***, которое последовательно считывает инструкции из памяти, дешифрует их и в соответствии с этим управляет всеми блоками процессора.
|
||||
|
||||
И даже при большом выборе моделей на рынке, в новых инженерных и научных областях все больше и больше применяются специализированные решения на основе *программируемых логических интегральных схем* (ПЛИС, *англ*. FPGA) - микросхем с реконфигурируемой структурой. Разработка проектов на ПЛИС практически всегда ведется с использованием *языков описания аппаратуры*(hardware description language, HDL). Одним из наиболее популярных языков является Verilog HDL. Мы рассмотрели его основные языковые конструкции.
|
||||
|
||||

|
||||
|
||||
В заключении было рассказано про такое понятие, как ***критический путь***. Сигналу требуется время, чтобы пройти через логический вентиль. Комбинационная схема, как правило, стоит из нескольких рядов цифровых вентилей. Так вот, критический путь, это самый длинный путь прохождения сигнала через схему. Другими словами, цепь с самой большой задержкой распространения сигнала от входа до выходы. Критический путь характеризует скорость работы устройства – чем он больше, тем дольше будет реакция устройства на изменение входного сигнала.
|
||||
|
||||

|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=oEsyRCdao9w) на видеозапись лекции
|
||||
2. Про основную структуру процессора и назначение его 4 основных блоков [**Кафедра ВТ**. *Микропроцессорные средства и системы* — Лекция 1.2]
|
||||
3. [Хорошая статья](https://tech-geek.ru/fpga/) о том, что такое ПЛИС и как это работает
|
||||
4. Пожалуй не самый удачный, но очень краткий обзор языка Verilog HDL [**Кафедра ВТ**. *Моделирование микропроцессорных систем на базе ПЛИС в САПР Quartus II* — параграфы 1.3 — 1.4]
|
||||
5. Про критический путь [**Харрис и Харрис**. *Цифровая схемотехника и архитектура компьютера —* параграф 2.9]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Снова про структуру процессора и его основные блоки, но другими словами, а в чем-то и подробнее [**Орлов и Цилькер**. *Организация ЭВМ и систем* — Глава 1. параграф 'Концепция машины с хранимой в памяти программой']
|
||||
2. [Классический курс](http://iosifk.narod.ru/hdl_coding/verilog.htm) по Verilog HDL на русском языке
|
||||
3. Наглядные примеры синтеза языка описания аппаратуры в цифровую схему. Вот только язык не Verilog HDL, а SystemVerilog, но они очень похожи. А еще параллельно разбирается язык VHDL — конкурент Verilog HDL. Можно сразу два языка подтянуть и увидеть в сравнении. Короче, рекомендую [**Харрис и Харрис**. *Цифровая схемотехника и архитектура компьютера —* Глава 4]
|
||||
|
||||
## Популярные материалы
|
||||
|
||||
Мне кажется очень удачные три коротенькие **видео-лекции** (9, 6 и 22 минуты соответственно) по основам Verilog HDL. Если не нравится, что парнишка говорит медленно, то в настройках его можно ускорить и лекции станут еще короче. Наслаждайся:
|
||||
|
||||
1. [Verilog. Модули. Симуляция](https://www.youtube.com/watch?v=xA7rl2a4vmI)
|
||||
2. [Комбинационная логика](https://www.youtube.com/watch?v=pMrJkHk10wU)
|
||||
3. [Последовательностная логика](https://www.youtube.com/watch?v=Vdz7_wMFAy)
|
55
Lectures/03. Digital arithmetics.md
Normal file
55
Lectures/03. Digital arithmetics.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Лекция 3. Цифровая арифметика. Арифметико-логическое устройство
|
||||
|
||||
На этой лекции мы вспомнили как складываются числа, на примере сложения в столбик. Для двоичных и десятичных чисел это делается одинаково. Разряды чисел складываются с учетом переносов от прошлых разрядов.
|
||||
|
||||

|
||||
|
||||
Особенностью цифровой арифметики является то, что она модульная, то есть ограничена некоторым максимальным числом, больше которого не существует. В данном случае модульная арифметика ограничена разрядностью цифрового устройства. Например, 3-битный сумматор не может выдать число, больше 111, то есть 7 в десятичной системе счисления. Можно сказать, что в такой арифметике не числовая прямая, а числовой круг. Операции сложения и вычитания — это движение по этому кругу в одну или в другую сторону. Благодаря особенностям такой арифметики можно выполнять вычитание используя операцию сложения. Выражение (**A — B**) эквивалентно выражению (**A + ~B + 1**). При этом к числам можно относиться либо как к беззнаковым (только положительным), либо как к знаковым (в таком случае старший бит числа указывает на знак, 1 — минус).
|
||||
|
||||

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

|
||||
|
||||
Операции сложения и вычитания выполняются на об одном из основных модулей процессора — сумматоре. Он строится из нескольких простых *однобитных полных сумматоров*, складывающих три бита: по одному биту от каждого из операндов и входной бит переноса (от предыдущего разряда), и формировать в качестве результата два бита: бит суммы и бит переноса для следующего разряда.
|
||||
|
||||

|
||||
|
||||
Чем больше однобитных сумматоров, тем выше разрядность обрабатываемых данных — это хорошо. Однако, в таком случае удлиняется и цепь переноса проходящая через все разряды, а значит удлиняется критический путь, то есть устройство работает медленнее — это плохо.
|
||||
|
||||

|
||||
|
||||
Если вложиться хитростью и дополнительными аппаратными затратами, то можно реализовать ускоренный перенос, уменьшающий критический путь. К таким устройствам относятся *схема с ускоренным переносом* и *префиксный сумматор*.
|
||||
|
||||
Один из основных операционных устройств (то есть устройств, выполняющих операции над данными) является АЛУ (арифметико-логическое устройство). *АЛУ — это комбинационная схема* выполняющая различные арифметические и поразрядно логические (то есть не использующие бит переноса) операции над входными данными. Выполняемая операция определяется управляющими сигналами. Помимо результата на выходе могут формироваться флаги, например, переполнения, знак результата и тому подобное.
|
||||
|
||||
Мы рассмотрели два основных подхода к проектированию. При первом подходе операции над данными мультиплексируются, и выбор операции происходит за счет управления мультиплексором.
|
||||
|
||||

|
||||
|
||||
В рассмотренном АЛУ поддерживается 7 операций (операция 011 бессмысленна). Плюс такого подхода — простота проектирования, простота изменения структуры.
|
||||
|
||||
Другой подход к построению АЛУ предполагает выведения оптимальных выражений, в которых конкретные значения управляющих сигналов преобразуют выражение так, чтобы оно выполняло требуемую операцию. В рассмотренном примере поддерживается 48 операций (но некоторые повторяются).
|
||||
|
||||

|
||||
|
||||
*S* — управляющее слово, *a*, *b* — операнды, *P* — перенос, *M* — выключатель переноса, *R* - результат операции. Индексы внизу указывают на то, что выражение относится к отдельному *i*-ому биту результата.
|
||||
|
||||
Например, чтобы выполнить операцию A ИЛИ B, надо подать управляющие сигналы S = 0001, M = 0, тогда в выражении R сократятся импликанты с S3, S2, S1 и M, потому что они равны нулю, и останется только R = a | b. Разработка, отладка и изменение конфигурации таких АЛУ сложнее, чем при первом подходе, однако можно получить гораздо больше (пусть и не часто используемых) операций, при меньшем критическом пути.
|
||||
|
||||
В конце лекции посмотрели на организацию блоков сравнения, логического и арифметического сдвигов.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=eXW6Q4jPkmQ) на видеозапись лекции
|
||||
2. Как и всегда в этом источнике, отличное доступное описание работы и принципов построения сумматоров, в том числе с ускоренным и префиксным переносом, компараторов, АЛУ и схем сдвига [**Харрис и Харрис**. *Цифровая схемотехника и архитектура компьютера —* параграфы 5.2.1 — 5.2.5]
|
||||
3. Про вариант синтезируемого через выражения АЛУ читай тут [**Кафедра ВТ**. *Микропроцессорные средства и системы* — Лекция 1.2]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Еще один вариант АЛУ, с коротким описанием на страничку, можно посмотреть тут [**Таненбаум и Остин**. *Архитектура компьютера* — Глава 3., Основные логические схемы, Арифметические схемы, подраздел Арифметико-логические устройства]
|
||||
|
||||
## Популярные материалы
|
||||
|
||||
1. Если есть хоть малейшая толика непонимания ***как*** все происходит внутри сумматора и ***как*** это все может быть физически реализовано, то крайне рекомендую посмотреть это 14-минутное [видео](https://www.youtube.com/watch?v=YuSgZ173Utg), в котором очень доступно все рассказано
|
59
Lectures/04. Operations units.md
Normal file
59
Lectures/04. Operations units.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Лекция 4. Операционные устройства
|
||||
|
||||
На лекции говорили про операционные устройства, то есть устройства выполняющие операции над данными. На фоне этого затронули основной компромисс цифрового дизайна — повышение скорости работы требует увеличения аппаратных затрат.
|
||||
|
||||
Самый экономный способ расходования аппаратуры — это использование последовательных однобитных устройств (ОПБ — операционный блок), то есть таких, которые получают результат бит за битом. Следовательно, на расчёт *n*-битного числа потребуется *n* тактов.
|
||||
|
||||

|
||||
|
||||
Быстрой альтернативой, но требующей гораздо больших аппаратных затрат, является параллельные операционные устройства, высчитывающие сразу весь результат.
|
||||
|
||||
Например, параллельный умножитель *k*-разрядных чисел, потребует использования *k*-1 *k*-разрядных сумматора.
|
||||
|
||||

|
||||
|
||||
При реализации последовательного умножения можно обойтись одним (*k* * 2)-разрядным сумматором, и даже меньше, если последовательно вычислять частные суммы произведения.
|
||||
|
||||

|
||||
|
||||
Еще одной важной темой, которую мы затронули, пыли числа с фиксированной и плавающей запятой. Числа с фиксированной запятой фактически не отличаются от целых чисел. Их недостаток в том, что если после запятой оставить много знаков, то будет проблематично записать большое число. А если оставлять мало чисел после запятой, то наоборот. Проблему частично решают числа с плавающей точкой (запятой).
|
||||
|
||||
Общепринятым стандартом являются числа закодированные по стандарту IEEE754. 32-битный формат таких чисел называют float, а 64-битный называют — double. Такой формат является экспоненциальной записью двоичного числа и содержит три поля Sign (Знак, 1 — если число отрицательное), Exponent (Показатель степени) и Mantissa, а число представляется как мантисса умноженная на 2 в степени экспоненты. При этом экспонента сохраняется в смещённом формате, то есть из ее закодированного значения надо предварительно вычесть 127. Мантисса же записывается так, чтобы точка в числе стояла сразу после первой значащей цифры. При этом эта единица в поле Mantissa не записывается. Она называется подразумеваемой единицей.
|
||||
|
||||

|
||||
|
||||

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

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

|
||||
|
||||
Согласно проведённому автором стандарта исследованию, числа закодированные posit имеют больший динамический диапазон, более равномерное распределение и обладают меньшим количеством неиспользуемых кодов.
|
||||
|
||||

|
||||
|
||||
Тема операционных устройств очень обширна и интересна. Чтобы повысить их производительность нужно прибегать к смекалке и хитрости, искать оригинальные математические решения. Сегодня такая задача часто возникает, например, при построении нейроускорителей выполняющих огромное количество операций сложения и умножения. К сожалению, подробный разбор существующих методов далеко выходит за рамки выделенного времени. Если тебя зацепило, в дополнительной литературе будут ссылочки.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=7YQWjSkhquI) на видеозапись лекции
|
||||
2. Понятно, наглядно и доступно про умножение и деление целых беззнаковых чисел [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — параграфы 5.2.6, 5.2.7]
|
||||
3. Наглядно про представление и сложение чисел с фиксированной и плавающей запятой (стандарт *IEEE754*) [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — параграф 5.3]
|
||||
4. Про вспомогательные системы счисления, переполнение при операциях со знаковыми числами и про умножение и деление знаковых чисел с фиксированной и с плавающей запятой. Автор суховат. Написать можно было бы доступней, но написано так, как написано. Если внимательно читать, то все понятно [***Орлов и Цилькер***. *Организация ЭВМ и систем* — Глава 5. начиная с параграфа 'Вспомогательные системы счисления' и до конца Главы останавливаясь на интересующих темах]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Что касается различных оригинальных методов реализации цифровой арифметики (сложение, деление) со знаком и плавающей запятой, это находится там же где и 3 источник в основных материалах к лекции [***Орлов и Цилькер***. *Организация ЭВМ и систем* — Глава 5. начиная с параграфа 'Вспомогательные системы счисления' и до конца Главы]
|
||||
2. Про стандарт posit можно почитать в статье со средне-хорошим переводом на [хабре](https://habr.com/ru/post/465723/) или сразу в [оригинале](http://www.johngustafson.net/pdfs/BeatingFloatingPoint.pdf)
|
||||
3. Есть отличная книга по цифровой операционным устройствам [Digital arithmetic](https://www.sciencedirect.com/book/9781558607989/digital-arithmetic). Она на английском языке. Для ознакомления в образовательных целях ее можно найти в облаке в разделе Литература → Дополнительно
|
||||
|
||||
## Популярные материалы
|
||||
|
||||
1. [Наглядно](https://cse512-19s.github.io/FP-Well-Rounded/) про распределения чисел в кодировке *posit* на числовой прямой (круге вообще-то) на разных интервалах и масштабах
|
||||
2. Есть [потрясающий сайт](http://nandgame.com/). *Частично* на русском. Построенный в игровой форме симулятор сборки процессора. Игрок постепенно, выполняя задания с подсказками от простого к сложному, собирает процессор. При желании не обязательно игру проходить сразу полностью, можно это делать по мере изучения материала, для подкрепления, так сказать. Игра очень наглядна, а у тебя, возможно, есть друг, который сюда не заглядывает и делает все в последний момент. Наглядная **игра** ему не помешает. Давай, не ломайся, кинь ему ссылочку на сайт, он поиграет, разберется, а ты, наверняка, пройдешь больше, сможешь потом ходить и с видом борзой уточки говорить: «а я больше тебя прошел :Р». Короче, скорее [заглядывай внутрь](http://nandgame.com/)! Но лучше это делать с компьютера или ноутбука. Развлекайся
|
||||
|
||||

|
40
Lectures/05. Sequencial logic.md
Normal file
40
Lectures/05. Sequencial logic.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# Лекция 5. Последовательностная логика
|
||||
|
||||
Основной темой лекции было запоминание информации. В основе простейшей ячейки памяти лежит бистабильное устройство, то есть такое, которое может стабильно находиться в одном из двух состояний сколь угодно долго. Таким устройством является два инвертора подключённые друг в друга — выход одного на вход другого. Чтобы иметь возможность менять сохраняемое значение, на входы инверсий можно поместить логическое ИЛИ. С помощью образовавшихся свободных входов можно менять значение, которое в нем хранится. Полученное устройство называется RS-триггер, потому что при подаче 1 на вход R (reset) сохраняется 0, а при подаче 1 на вход S (set) сохраняется 1.
|
||||
|
||||

|
||||
|
||||
Не очень удобный интерфейс для использования. Вдобавок у триггера есть запрещенное состояние, при котором логика работы устройства нарушается (Q == ~Q?). Указанную проблему можно легко устранить, доработав RS-триггер до D-защелки. *Защелка* (latch), сохраняет входные данные по уровню разрешающего сигнала. Пока на CLK подается 1, говорят, что защелка является прозрачной, то есть она повторяет на выходе то, что приходит на ее вход D. Когда CLK равняется 0, защелка хранит информацию.
|
||||
|
||||

|
||||
|
||||
Если подумать, то по времени оптимальнее, когда запоминание происходит по фронту сигнала, таким образом можно достичь максимальной производительности. Соединяем последовательно две защелки с инвертированным разрешением на запись, и *триггер*, запоминающий информацию в момент фронта сигнала CLK (момент переключения с 0 на 1), готов!
|
||||
|
||||

|
||||
|
||||
Соединив синхроимпульсы нескольких триггеров с целью хранения одной порции данных получаем *регистр* — ячейка памяти хранящая сразу несколько бит информации.
|
||||
|
||||

|
||||
|
||||
Регистр имеет разрядность (битность). Если соединить несколько регистров с возможностью доступа к каждому по адресу, то получится *регистровый файл*. Его так же называют блоком регистров общего назначения (БРОН). Регистровые файлы используют для хранения операндов и промежуточных результатов при работе с АЛУ. Количество портов памяти определяется количеством ячеек памяти к которым можно одновременно обратиться, другими словами, количеством адресных входов. Например, регистровый файл представленный ниже имеет два порта на чтение и один порт на запись. При этом по адресу 0 находится константное значение 0. Для реализации адресуемости используются мультиплексоры и демультиплексоры.
|
||||
|
||||

|
||||
|
||||
Кроме этого поговорили про синхронизацию в цифровых устройствах, основной вывод таков — чем короче комбинационная схема, тем выше частота работы. Так же скорость работы цифровых устройств зависит от временных особенностей регистров, используемых в этом устройстве. Триггерам, в составе регистров, требуется чтобы сигнал был устоявшимся в течении некоторого времени перед фронтом синхроимпульса (tsetup), плюс, требуется время для того, чтобы на выходе регистра сформировался установившийся сигнал (tpcq).
|
||||
|
||||

|
||||
|
||||
В конце лекции затронули тему конечных автоматов — устройств, способных находиться в одном из конечном количестве состояний. Процессор является гигантским автоматом состояния. Лекция закончилась демонстрацией программируемого устройства с примитивной архитектурой и примером программы, написанной для него.
|
||||
|
||||

|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=Ca32opNonyw) на видеозапись лекции
|
||||
2. Большая часть лекции опиралась на этот хорошо написанный материал с иллюстрациями про защелки и триггеры [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — параграфы раздела 3.2]
|
||||
3. Еще немного из этой же книги но про синхронизацию, расфазировку и метастабильность [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — параграфы раздела 3.5]
|
||||
4. Описание и принцип работы программируемого устройства, разобранного устройства в конце лекции, можно встретить в методическом описании к 3 лабораторной работе для групп ПИН, в соответствующей папке в [облаке](https://1drv.ms/u/s!AlYsTGjsjfIfhP4GhdRLPQzK60vqGw)
|
||||
|
||||
## Дополнительные материалы для саморазвития
|
||||
|
||||
1. Отличный разбор о том, что такое конечный автомат, зачем это нужно и как его спроектировать [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — параграфы раздела 3.4]
|
98
Lectures/06. RISC-V architecture.md
Normal file
98
Lectures/06. RISC-V architecture.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Лекция 6. Архитектура RISC-V
|
||||
|
||||
***Система команд*** процессора — это все команды, выполнение которых аппаратно поддерживается процессором. ***Архитектура системы команд*** (Instruction Set Architecture, ISA) включает в себя систему команд и средства для их выполнения, такие как форматы данных, системы регистров, способы адресации, модели памяти. Лекция была посвящена обзору ISA RISC-V и её особенностей.
|
||||
|
||||
RISC (Reduced Insrtuction Set Computer) — архитектура с сокращённым набором команд. В таких архитектурах поддерживается относительно небольшой набор простых инструкций (обычно до 100), притом все они имеют одинаковый размер. RISC также является load/store архитектурой, это значит, что для того, чтобы выполнить какую-либо операцию над данными, их необходимо предварительно разместить в регистровом файле. Все операции происходят только с данными в регистровом файле, а для доступа к основной памяти используются специальные инструкции типа load и store.
|
||||
|
||||
RISC-V является RISC-архитектурой (мы рассматриваем исключительно её 32-битный вариант). Регистровый файл включает 32 регистра общего назначения, кроме регистра по адресу 0, там находится константное значение 0 (записать в него ничего не получится). Все регистры 32 -битные. АЛУ выполняет операции только над данными размещёнными в регистровом файле. Основная память имеет побайтовую адресацию, при этом считывать из памяти можно байты, полуслова (16 бит) и слова (32 бита).
|
||||
|
||||

|
||||
|
||||
Побайтовая адресация с выровненным доступом подразумевает, что каждый байт памяти имеет свой уникальный адрес, при этом можно считать или записать также полуслово или слово, в таком случае должен быть указан адрес младшего байта, входящего в состав этого полуслова или слова. Существуют два способа организации порядка следования байт: Big-Endian и Little-Endian, при этом внутри отдельного байта число хранится обычным образом — слева старший бит, справа — младший.
|
||||
|
||||

|
||||
|
||||
Каждая инструкция кодируется 32 битами. Чтобы не использовать инструкции представленные в машинном коде (нулями и единицами), их записывают с помощью инструкций языка ассемблера. Язык ассемблера представляет собой машинные коды, записанные в виде понятной человеку мнемоники. Например, машинная инструкция 00000000001100010111000010000011 для RISC-V записывается на языке ассемблера как and x1, x2, x3 — это понятней и наглядней, чем машинная инструкция. Разные архитектуры процессоров имеют разные ассемблеры.
|
||||
|
||||
Типичная команда ассемблера начинается с короткого слова, указывающего **что** нужно сделать, далее указывается **с какими данными** это надо сделать. Названия регистров состоят из буквы x и номера регистра, например, x10 — это десятый регистр регистрового файла.
|
||||
|
||||
Базовый набор целочисленных инструкций архитектуры RISC-V включает в себя:
|
||||
|
||||
- 10 вычислительных инструкций, использующих в качестве двух операндов значения из регистров, и помещающее результат в регистровый файл
|
||||
|
||||
```assembly
|
||||
add x4, x3, x2 # сложение x4 = x3 + x2
|
||||
or x8, x5, x1 # логическое ИЛИ x8 = x5 | x1
|
||||
sll x5, x4, x3 # логический сдвиг влево x5 = x4 << x3
|
||||
# и тому подобное
|
||||
```
|
||||
|
||||
- 9 вычислительных инструкций, использующих в качестве одного из операндов регистр из регистрового файла, а второго — константу из инструкции
|
||||
|
||||
```assembly
|
||||
addi x4, x3, -5 # сложение x4 = x3 + (-5)
|
||||
srli x5, x4, 2 # логический сдвиг вправо x5 = x4 >> 2
|
||||
# и тому подобное
|
||||
```
|
||||
|
||||
- 8 инструкций для перемещения данных между регистровым файлом и основной памятью, использующих косвенно-регистровую адресацию со смещением (это значит, что адрес ячейки в основной памяти вычисляется как сумма базового регистра и смещения)
|
||||
|
||||
```assembly
|
||||
lw x4, 8(x7) # загрузить слово (32 бита) из памяти
|
||||
# по адресу x7 + 8 в регистр x4
|
||||
lbu x3, 0(x2) # загрузить беззнаково байт (8 бит) из памяти
|
||||
# по адресу x2 + 0 в регистр x3
|
||||
sw x2, 16(x5) # переместить данные из регистра x2 в память по адресу x5 + 16
|
||||
```
|
||||
|
||||
- 6 инструкций условного перехода, сравнивающих значение из двух регистров
|
||||
|
||||
```assembly
|
||||
beq x14, x15, label # если x14 == x15, то PC = PC + label
|
||||
blt x20, x21, label # если x20 < x21, то PC = PC + label
|
||||
# label - это метка, представляющее собой обычное число
|
||||
```
|
||||
|
||||
- 2 инструкции безусловного перехода с сохранением адреса возврата
|
||||
|
||||
```assembly
|
||||
jal x3, label # x3 = PC + 4; PC = PC + label
|
||||
```
|
||||
|
||||
И ещё несколько специфических инструкций. Полный список базовых целочисленных инструкций форматы их кодирования приводится ниже.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
Кроме озвученных инструкций существуют и псевдоинструкции - псевдонимы существующих инструкций для упрощенного программирования на ассемблере. Например, инструкция
|
||||
|
||||
```assembly
|
||||
mv x2, x1 # переместить данные из регистра x1 в x2
|
||||
```
|
||||
|
||||
на самом деле является инструкцией
|
||||
|
||||
```assembly
|
||||
addi x2, x1, 0
|
||||
```
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=wMhUfqiBj5M) на видеозапись лекции
|
||||
2. Все материалы лекции можно найти в этом источнике, к сожалению аналога на русском пока не нашел [***Patterson Hennessy***. *Computer organization and design. RISC-V edition* — 2 глава]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Понятный разбор очень похожей архитектуры MIPS [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — параграфы 6.1, 6.2]
|
||||
2. Еще один годный разбор другой популярной RISC архитекрутры — ARM [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера. Дополнение по архитектуре ARM* — параграфы 1.1, 1.2]
|
||||
3. Обзор популярной тройки: x86, ARM, AVR [***Таненбаум и Остин***. *Архитектура компьютера* — Глава 5]
|
||||
|
||||
## Популярные материалы
|
||||
|
||||
1. На [этом](https://www.kvakil.me/venus/) сайте можно сразу писать код на языке ассемблера RISC-V, запускать, отлаживать, а потом еще и машинный код сохранить себе
|
||||
2. [Расширение](https://marketplace.visualstudio.com/items?itemName=hm.riscv-venus) для VSCode ассемблера и дебаггера RISC-V
|
||||
3. Немного [мёда](https://www.terraelectronica.ru/news/6423) про RISC-V
|
||||
4. Отличнейшая популярная книга о цифровой схемотехнике и архитектуре компьютера, рекомендую заглянуть в нее при любом уровне понимания материала. Объем не большой, страницы маленькие, буквы большие, за пару полных вечеров вполне читается, многое проясняет и ставит на место [***Чарльз Петцольд***. *Код. Тайный язык информатики*]
|
||||
|
||||

|
102
Lectures/07. RISC-V programming.md
Normal file
102
Lectures/07. RISC-V programming.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Лекция 7. Программирование RISC-V
|
||||
|
||||
В подавляющем большинстве случаев, современные программы пишутся на языках высокого уровня. Процессоры не понимают языков высокого уровня, поэтому компиляторы переводят текст (программу), написанный на языке высокого уровня в последовательность простых инструкций языка ассемблера. После этого, программу на языке ассемблера переводят в последовательность машинных команд — то, что понятно процессору.
|
||||
|
||||
На лекции было разобрано несколько примеров основных синтаксических конструкций языка высокого уровня C. Условный оператор if реализуется за счёт использования инструкций условного перехода.
|
||||
|
||||
```c
|
||||
if (/*условие*/) {
|
||||
//тело условия если True
|
||||
} else {
|
||||
// тело условия если False
|
||||
}
|
||||
```
|
||||
|
||||
```assembly
|
||||
# условие вычисляется в xN регистр
|
||||
beqz xN, else
|
||||
#тело условия если True для if
|
||||
j endif
|
||||
else:
|
||||
#тело условия если False для if
|
||||
endif:
|
||||
```
|
||||
|
||||
Оператор цикла while также реализуется за счёт применения инструкций условного перехода.
|
||||
|
||||
```c
|
||||
while (/*условие*/) {
|
||||
// тело цикла
|
||||
}
|
||||
```
|
||||
|
||||
```assembly
|
||||
while:
|
||||
# условие вычисляется в xN
|
||||
beqz xN, endwhile
|
||||
# тело цикла
|
||||
j while
|
||||
endwhile:
|
||||
```
|
||||
|
||||
Процедуры (они же функции или подпрограммы) – это повторно используемые фрагменты кода, реализующие вычисления определённой задачи. Использование процедур позволяет абстрагироваться и повторно использовать один и тот же код, но с разными входными параметрами. Большие программы состоят из подпрограмм, включающих в себя другие подпрограммы и так далее.
|
||||
|
||||
Программа, которая вызывает подпрограмму называется *вызывающей*. Подпрограмма которую вызывают называется *вызываемой* подпрограммой. Вызывающая программа использует тот же набор регистров, что и вызываемая, поэтому: либо вызывающая, либо вызываемая должна сохранять регистры вызывающей в памяти и восстанавливает их, когда процедура завершает своё выполнение.
|
||||
|
||||
Вызов подпрограммы означает передачу управления этой подпрограмме, то есть загрузки в PC (program counter, указатель на инструкцию) адреса первой инструкции вызываемой подпрограммы. Чтобы вернуться к месту вызова процедуры, когда выполнение подпрограммы закончится, при её вызове необходимо использовать специальную инструкцию jal (jump and link).
|
||||
|
||||
Соглашение о вызовах устанавливает правила использования регистров между процедурами. В соглашении о вызовах RISC-V даются символические имена регистров x0 — x31 для обозначения их роли. Вызываемая подпрограмма получает аргументы через регистры a0 — a7. В таблице ниже приводится указывается какие из регистров должны быть сохранены неизменными при возврате из подпрограммы, и, какие регистры следует сохранить перед вызовом подпрограммы, если их содержимое планируется использовать после.
|
||||
|
||||

|
||||
|
||||
Каждый вызов процедуры имеет свой собственный экземпляр данных, включающий: аргументы функции, содержимое регистрового файла и адрес возврата, и называемый *активационной записью*. Для хранения активационных записей функций используется стек, занимающий часть основной памяти. Стек — это способ организации памяти, при котором первая запись будет считана в последнюю очередь (LIFO — last-in-first-out). Для поддержания работы стека используется регистр x2, также именуемый sp (Stack Pointer — указатель стека), который указывает на последнюю ячейку памяти помещённую в стек. Далее приводится пример вызова подпрограммы с сохранением сохраняемых регистров на стек.
|
||||
|
||||
```assembly
|
||||
addi sp, sp, -8 # выделить место на стеке для двух элементов
|
||||
sw ra, 0(sp) # сохранить регистр ra на стек
|
||||
sw a1, 4(sp) # сохранить регистр a1 на стек
|
||||
jal ra, func # сохранить в ra адрес возврата PC+4 и перейти к func
|
||||
lw ra, 0(sp) # восстановить из стека значение ra
|
||||
lw a1, 4(sp) # восстановить из стека значение a1
|
||||
addi sp, sp, 8 # освободить место на стеке
|
||||
|
||||
func: # вызываемая функция
|
||||
addi sp, sp, -4 # выделить место на стеке
|
||||
sw s0, 0(sp) # сохранить регистр s0 на стеке
|
||||
# ...... некий код, выполнение функции, использующей регистр s0
|
||||
lw s0, 0(sp) # восстановить из стека значение s0
|
||||
addi sp, sp, 4 # освободить место на стеке
|
||||
jr ra # вернуться в основную программу
|
||||
```
|
||||
|
||||
Большинство языков программирования (в том числе C) используют три отдельных области памяти для данных:
|
||||
|
||||
- **Stack**: Содержит данные используемые процедурными вызовами. Регистр sp указывает на вершину стека
|
||||
|
||||
- **Static**: Содержит глобальные переменные, которые существуют в течении всего времени жизни программы. Регистр gp (Global Pointer) указывает на начало этой области
|
||||
|
||||
- **Heap**: Содержит динамически-распределяемые данные и растёт в сторону старших адресов. В C программист управляет кучей в ручную, размещая новые данные с помощью malloc() и освобождая с помощью free(). В Python, Java, и большинстве современных языков, куча управляется автоматически
|
||||
|
||||
- **Text**: область памяти содержащая программный код
|
||||
|
||||

|
||||
|
||||
Также на лекции затронули вопрос компиляции программ с языков высокого уровня. Этот процесс происходит в несколько этапов. Сначала высокоуровневый код компилируется в код на языке ассемблера, который затем ассемблируется в машинный код и сохраняется в виде объектного файла. Компоновщик, также называемый редактором связей или линкером (linker), объединяет полученный объектный код с объектным кодом библиотек и других файлов, в результате чего получается готовая к исполнению программа. На практике, большинство компиляторных пакетов
|
||||
выполняют все три шага: компиляцию, ассемблирование и компоновку. Наконец, загрузчик загружает программу в память и запускает её.
|
||||
|
||||

|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=y1mNFvm8OZY) на видеозапись лекции
|
||||
2. Все материалы лекции можно найти в этом источнике, к сожалению аналога на русском пока не нашел [***Patterson Hennessy***. *Computer organization and design. RISC-V edition* — 2 глава]
|
||||
3. Про процесс компиляции можно почитать, например, в этом источнике [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — весь параграф 6.6 с подпунктами]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. [Полезная информация](https://github.com/riscv/riscv-asm-manual/blob/master/riscv-asm.md) по программированию на языке ассемблера RISC-V, на английском языке
|
||||
2. [Здесь](http://skilldrick.github.io/easy6502/) можно познакомиться, разобраться и пописать ассемблерные программки под архитектуру 6502 — классический процессор, на котором работают Бендер, Терминатор и Денди. Давай-давай, не стесняйся, заходи. Прямо на странице есть встроенный симулятор и объясняют как написать простенькую игру — змейку. Если не в курсе, люди соревнуется, у кого она получится меньше по объёму кода. Да и вообще в интернете полно информации по этому процессору. Процитирую автора ресурса: 6502 is *fun*. Nobody ever called x86 *fun*. А [тут](https://museum.netstalking.ru/xaknotdie/02_nes_6502_asm.html) на русском про программирование 6502.
|
||||
|
||||
## Популярные материалы
|
||||
|
||||
1. В [этом](https://godbolt.org/) онлайн-компиляторе можно смотреть в какую последовательность ассемблерных инструкций скомпилируется твой код на C++ для самых разных архитектур. Можно, например, сравнить x86, ARM и RISC-V, при том разных версий компиляторов — чем отличается генерируемые инструкции процессору в каждом случае, где код длиннее, где требуется много подготовительных операций и тому подобное. В конце концов можно наглядно посмотреть разницу между программами для CISC и RISC архитектур
|
41
Lectures/08. Singlecycle processor.md
Normal file
41
Lectures/08. Singlecycle processor.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Лекция 8. Однотактный процессор RISC-V
|
||||
|
||||
Микроархитектура — это физическая модель процессора, описывающее из каких конкретно функциональных модулей состоит процессор и как они все в нем взаимодействуют. Существуют три способа построения микроархитектуры:
|
||||
|
||||
- **Однотактная** — выполняет всю команду за один такт. Ее принцип работы легко объяснить, а устройство управления довольно простое. Из-за того, что все действия выполняются за один такт, эта микроархитектура не требует никакого неархитектурного состояния (то есть никаких дополнительных регистров, требуемых для работы процессора, но недоступных для использования программистом). Однако, длительность такта ограничена самой медленной командой, использующей самый длинный критический путь
|
||||
- **Многотактная** — выполняет команду за несколько более коротких тактов. Простым командам нужно меньше тактов, чем сложным. Вдобавок, многотактная микроархитектура уменьшает количество необходимой аппаратуры путем повторного использования таких «дорогих» блоков, как сумматоры и блоки памяти
|
||||
- **Конвейерная** — результат применения принципа конвейерной обработки к однотактной микроархитектуре.
|
||||
|
||||
Архитектура процессора — это функциональная модель его возможностей.
|
||||
|
||||
К особенностям архитектуры RISC-V относится регистровый файл на 32 32-битных регистра общего назначения, при том регистр по адресу 0 имеет константное значение 0. RISC-V имеет load/store архитектуру, это значит, что для выполнения действий над данными их необходимо предварительно разместить в регистровом файле. Основная память имеет побайтовую адресацию с выровненным доступом, и из нее могут быть считаны слова, полуслова или байты.
|
||||
|
||||
Архитектура процессора определяет не только какими функциональными возможностями обладает процессор, но и каким именно образом кодируются инструкции в этой архитектуре.
|
||||
|
||||
В базовом наборе целочисленных инструкций RISC-V предусмотрено 6 форматов кодирования инструкций. Каким именно из этих форматов закодирована инструкция определяется полем opcode (код операции). Вспомогательными полями, определяющими команду являются funct3 и funct7. Поля rs1 и rs2 кодируют адреса операндов в регистровом файле. Поле rd кодирует адрес результата, сохраняемого в регистровый файл. Поле imm хранит в себе константу, непосредственный операнд. Соответствие opcode'ов операциям можно посмотреть в документации на RISC-V.
|
||||
|
||||

|
||||
|
||||
Ввиду своей простоты, в первую очередь был разработан процессор с однотактной микроархитектурой с архитектурой RISC-V. Тракт данных процессора состоит из счетчика команд (регистр PC — program counter), памяти инструкций (Instruction Memory), регистрового файла (Register File), арифметико-логического устройства (ALU), памяти данных (Data Memory) и основного дешифратора (Main Decoder). На входе PC располагается схема вычисления адреса следующей инструкции. Выход PC подключен к адресному входу памяти инструкций, тем самым выбирая инструкцию для исполнения. Часть битов считанной инструкции отправляются в основной дешифратор, который в зависимости от поля opcode, funst3 и funct7 формирует управляющие сигналы для всех блоков процессора.
|
||||
|
||||

|
||||
|
||||
Например, если очередная считанная инструкция является инструкцией сохранения слова из регистрового файла в основную память sw, то основной дешифратор (Main Decoder) "поймет" это по полю opcode и func3, которые поступает к нему на вход прямо из инструкции. В зависимости от поступивших opcode и полей func основной дешифратор формирует соответствующие управляющие сигналы (синие на схеме) для всех блоков процессора. Другими словами — направляет данные в тракте данных.
|
||||
|
||||

|
||||
|
||||
Как можно видеть, основной дешифратор должен соответствовать некоторой таблице истинности, а значит является обычной комбинационной схемой.
|
||||
|
||||
Основным преимуществом однотактной микроархитектуры является простота понимания ее работы. К минусам можно отнести: (1) относительно высокие аппаратные затраты из-за использования дополнительных сумматоров и раздельной основной памяти (гарвардская архитектура, отдельно память команд, отдельно память данных), (2) низкая тактовая частота из-за длинного критического пути, (3) так как резные инструкции проходят разный путь, скорость работы ограничена скоростью самой медленной инструкции.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=JlNvkVwDsVs) на видеозапись лекции
|
||||
2. К сожалению написанного материала по проектированию однотактного процессора именно с такой архитектурой на русском языке пока нет, поэтому в качестве альтернативы, если материалов озвученных на лекции недостаточно, можно познакомиться с очень похожим процессором, но с архитектурой MIPS. Полный процесс синтеза такого процессора можно посмотреть в этом источнике [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — параграфы 7.1 — 7.3.4]
|
||||
3. Рекомендуется ознакомиться с документацией на RISC-V, которая находится в [облаке](https://1drv.ms/u/s!AlYsTGjsjfIfhP4GhdRLPQzK60vqGw) в папке "Литература (только для ознакомления)"
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Непохожий на рассматриваемый на лекции пример. Непохож и сам подход к реализации микроархитектуры с названием Mic-1. Рекомендуется ознакомиться для расширения кругозора [***Таненбаум и Остин***. *Архитектура компьютера* — Глава 7. начиная с параграфа «Процесс ассемблирования»]
|
||||
2. Еще один синтез однотактного процессора, но с архитектурой ARM. Похоже на MIPS, но со своими тонкостями. А еще, чтобы усвоить материал придется предварительно прочитать всю первую главу книги про архитектуру ARM [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера. Дополнение по архитектуре ARM* — параграфы 2.1 — 2.3.4]
|
||||
3. Так же в папке "Литература (только для ознакомления)" в облаке, в разделе "Дополнительно" можно найти документ "Однотактный PIC", в котором разбирается проектирование однотактного процессора с архитектурой PIC
|
61
Lectures/09. Multicycle processor.md
Normal file
61
Lectures/09. Multicycle processor.md
Normal file
@@ -0,0 +1,61 @@
|
||||
# Лекция 9. Многотактный процессор RISC-V
|
||||
|
||||
Основными минусами однотактного процессора является: неэффективность использования аппаратуры и долгий тактовый импульс, ориентированный на выполнение самой длинной (долгой) инструкции.
|
||||
|
||||
Многотактная микроархитектура предполагает использование буферных (неархитектурных, то есть недоступных программисту) регистров, с целью уменьшения критического пути и поднятия таковой
|
||||
частоты. При этом каждая инструкцию будет выполняться несколько более коротких тактов, используя разное количество тактов для реализации разных инструкций.
|
||||
|
||||
Благодаря выполнению инструкции за несколько тактов, в этой микроархитектуре получилось реализовать принстонскую архитектуру (она же фоннеймановская, то есть данные и программы хранятся в одной памяти) и уменьшить количество сумматоров, за счет выполнения всех вычислительных операций на одном АЛУ. Еще одним из основных отличий от однотактной реализации является устройство управления (Control Unit), которой, в отличии от основного дешифратора (Main Decoder) однотактного процессора, является последовательностным устройством, а не комбинационным. Это значит, что в устройстве управления есть элементы памяти, и он ведет себя как автомат состояний (конечный автомат). Control Unit, в зависимости от выполняемой инструкции формирует *последовательность* управляющих сигналов, обеспечивающих движение данных по тракту данных от секции к секции, такт за тактом, пока инструкция не будет выполнена.
|
||||
|
||||

|
||||
|
||||
Устройство управления (УУ) для такого процессора может быть построено одним из двух способов:
|
||||
|
||||
- на жесткой логике (в таком случае, УУ является классическим конечным автоматом. Это наиболее быстрая реализация УУ, однако, его сложнее проектировать и отлаживать, чем второй подход, а после производства и выпуска работу устройства нельзя скорректировать)
|
||||
- устройство с микропрограммным управлением (по сути является маленьким программируемым устройством, хранящим последовательность управляющих сигналов для процессора в виде небольших микропрограмм, последовательно считываемых из управляющей памяти и выдаваемых на выходы Y — на схеме микроархитектуры отмечены синим цветом. Каждая инструкция процессора провоцирует запуск определенной микропрограммы из управляющей памяти).
|
||||
|
||||
Устройства с микропрограммным управлением (УМУ) сами могут быть построены одним из двух способов, отличающиеся способом адресации следующей микроинструкции:
|
||||
|
||||
- УМУ с принудительной адресацией
|
||||
- УМУ с естественной адресацией
|
||||
|
||||
В первом случае, каждая микроинструкция, помимо операционной части (где хранятся значения управляющих сигналов для процессора) присутствуют еще три поля: два поля адреса и поле признака, кодирующего информацию о том, какие флаги от операционных устройств надо проверить. Если флаги совпадают с указанными в микроинструкции, то следующей загружается микроинструкция по адресу из первого поля, в противном случае — из второго.
|
||||
|
||||
Такой подход плох тем, что одно поле адреса микроинструкции никогда не используется, так как всегда имеет смысл и выбирается только одно из двух. За счет этого увеличивается необходимый объем памяти, что приводит к замедлению скорости работы устройства (большая память = медленная память).
|
||||
|
||||

|
||||
|
||||
Альтернативный подход: УМУ с естественной адресации. В подобном устройстве микроинструкция состоит из 3 полей: операционная часть (либо адресная), поле флагов, которые надо проверить у операционных устройств и поле признака, сообщающее что сейчас в основной части (операция или адрес новой микроинструкции). В обычной ситуации, если поле признака равно 0, счетчик, в составе этого УМУ, с каждым таком увеличивается, указывая каждый раз на следующую микрокоманду. При этом в самой микрокоманде хранится операционная часть (управляющие сигналы для процессора). Но, если значения признака равно 1, это значит, что в микроинструкции вместо операционной части находится адрес, который будет загружен в счетчик, если флаги указанный в микрокоманде соответствуют флагам, поступаемых от операционных устройств.
|
||||
|
||||

|
||||
|
||||
Такой подход позволяет значительно уменьшить управляющую память, за счет чего она получится быстрее. Однако, микроинструкции ветвления, при таком подходе, требуют дополнительного такта на обработку (когда признак равен 1 нет операционной части).
|
||||
|
||||
Когда управляющая память хранит значения всех сигналов процессора в естественной форме, это называется *горизонтальным микропрограммированием*. Это значит, что, если устройство управления должно формировать, например, 50 управляющих сигналов для всех блогов процессора, то каждая микроинструкция будет включать в себя операционную часть длинной в 50 бит, то есть отдельный бит для каждого управляющего сигнала.
|
||||
|
||||
Горизонтальное микропрограммирование не требует наличие дешифратора на выходе УМУ, однако, для хранения всех значений сигнала потребуется относительно большая память, что повлияет на скорость ее работы. Альтернативой является *вертикальное микропрограммирование*, в котором каждой длинной последовательности сигналов (например, 50 в нашем примере) ставится в соответствие более короткая последовательность (например, из 10 бит). В таком случае на выходе УМУ требуется расположить дешифратор, который будет преобразовывать короткий код в длинный.
|
||||
|
||||
С одной стороны это уменьшает объем требуемой памяти (хорошо отражается на ее скорости), но дешифратор сам имеет задержку распространения сигнала, а значит уменьшает эффект от уменьшения ее объема.
|
||||
|
||||
Золотая середина — *квазивертикальное* (*горизонтально-вертикальное*) *микропрограммирование*, при котором стараются найти баланс между степенью сжатия микроинструкций и величиной дешифратора на выходе УМУ.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=xHefXrFNI0M) на видеозапись лекции
|
||||
2. По вопросу синтеза многотактного процессора та же проблема с литературой. Либо смотреть запись лекции, либо ориентироваться на полный процесс синтеза многотактного процессора в тексте, но на примере архитектуры MIPS [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — весь параграф 7.4]
|
||||
3. Про устройство управления с жесткой логикой и с микропрограммным управлением [***Кафедра ВТ***. *Микропроцессорные средства и системы* — Лекция 2.1]
|
||||
|
||||
## Дополнительные материалы для саморазвития
|
||||
|
||||
1. Более развернутое, однако при этом и более сухое, описание вариантов реализации устройства управления. В этом источнике, например, разбирается нанопрограммное управление, которое не затрагивалось на лекции, и есть пример реализации УУ на жесткой логике (тут, правда, это называется аппаратной логикой — суть одна) [***Орлов и Цилькер***. *Организация ЭВМ и систем* — Глава 4. три параграфа начинающиеся со слов 'Микропрограммный автомат…']
|
||||
2. Еще один синтез многотактного процессора, но с архитектурой ARM. Похоже на RISC-V и MIPS, но со своими тонкостями. А еще, чтобы усвоить материал придется предварительно прочитать всю первую главу книги про архитектуру ARM [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера. Дополнение по архитектуре ARM* — весь параграф 2.4]
|
||||
|
||||
## Популярные материалы
|
||||
|
||||
1. [Обязательно к просмотру!](http://buthowdoitknow.com/cpu_model_intro.html) Рабочая модель процессора с многотактной микроархитектурой и устройством управления с жесткой логикой (с кольцевым счетчиком, все как положено). [Тут](http://buthowdoitknow.com/but_how_do_it_know_cpu_model.html) можно прямо в браузере написать программку и посмотреть потактово\покомандно ее исполнение, рассматривая откуда и куда идут сигнальчики, вникая в самую суть происходящего. Очень интересно и увлекательно.
|
||||
|
||||
Чтобы было понятней происходящее, надо прочесть [описание](http://buthowdoitknow.com/cpu_model_intro.html), либо нажать Details под [схемой](http://buthowdoitknow.com/but_how_do_it_know_cpu_model.html). Нажав на Load sample multiplying 5x5 в открывшемся окне, в окно программы загрузиться стандартный пример, за которым можно понаблюдать при первом ознакомлении с моделью.
|
||||
|
||||
А еще на странице проекта можешь найти вариант модели процессора на Excel.
|
||||
|
||||

|
52
Lectures/10. Pipeline processor.md
Normal file
52
Lectures/10. Pipeline processor.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Лекция 10. Конвейерный процессор RISC-V
|
||||
|
||||
На лекции мы пришли к выводу, что если выполнение инструкций в однотактном процессоре лишь последовательно задействует его функциональные блоки (то есть в каждый момент времени задействован только один из них, а остальные ожидают), то разумным шагом будет поставить между ними буферные регистры, назвать это ступенями и одновременно, как на конвейере (да хоть конвейер по производству останкинских сосисок себе представь — одна суть), обрабатывать несколько подряд идущих инструкций, каждая на своей ступени. Хотя каждой отдельно взятой инструкции надо пройти все стадии конвейера, то есть выполнение происходит за несколько тактов, команды «сходят» с конвейера на *каждом* такте. Время выполнения одной инструкции называется *латентностью*. Скорость обработки инструкций называется *пропускной способностью* конвейера. Ниже приводится сравнение работы однотактного и конвейерного процессора.
|
||||
|
||||

|
||||
|
||||
Латентность инструкций в конвейерном процессоре выше, чем у однотактного процессора, то есть одна отдельно взятая инструкция выполняется дольше, чем, например, в однотактном процессоре. Однако, пропускная способность конвейера гораздо выше, чем в однотактной микроархитектуре, так как на каждом такте заканчивает выполняться очередная инструкция.
|
||||
|
||||
Критический путь у такой реализации короче однотактной, но длиннее многотактной, однако, по производительности это решение наиболее успешное.
|
||||
|
||||

|
||||
|
||||
На лекции был реализован классический конвейер, состоящий из 5 стадий (ступеней):
|
||||
|
||||
1. Fetch (выборка инструкции из памяти программ. Включает в себя PC и Instruction Memory)
|
||||
2. Decode (дешифрация инструкции и подготовка операндов. Включает в себя Main Decoder, Register File и блоки знакорасширения, подготавливающих константы)
|
||||
3. Execute (выполнение инструкции. Включает в себя мультиплексоры и ALU)
|
||||
4. Memory (обращение к памяти данных. Включает в себя Data Memory)
|
||||
5. Writeback (запись результата в регистровый файл. Включает в себя мультиплексор и порт записи Register File)
|
||||
|
||||
Не смотря на главный плюс конвейерной реализации (скорость), ее главным минусом является необходимость устранения конфликтов. Конфликт конвейера — это ситуация, при которой конвейер должен приостановиться, чтобы выполнение очередной инструкции не нарушило работу программы. Они возникают из-за параллельного выполнения нескольких инструкций на разных стадиях конвейера, так как из-за зависимостей не любые из них могут обрабатываться параллельно. Например, типичным конфликтом конвейера является конфликт по данным, который может возникнуть, если очередная инструкция пытается считать данные из регистрового файла, которые предшествующая инструкция еще не успела там разместить.
|
||||
|
||||

|
||||
|
||||
Указанный конфликт решается переброской результата операции с более поздних ступеней назад, чтобы этим результатом можно было воспользоваться до того, как он окажется в регистровом файле. Данный подход не помогает при инструкциях обращения к памяти, так как считываемый операнд может потребоваться до того, как он будет считан из памяти. В таком случае приходится приостанавливать конвейер и очищать стадий, в которые были загружены недостоверные данные. Ситуация, в которой в конвейер помещают нули (очищают стадии) называется пузырьком.
|
||||
|
||||
Разрешением конфликтов занимается блок устранения конфликтов (Hazard Unit), который в автоматическом режиме их обнаруживает и предпринимает необходимые действия по их устранению.
|
||||
|
||||

|
||||
|
||||
Существуют три вида конфликтов конвейера:
|
||||
|
||||
- Структурные (вызванные несовершенностью аппаратной части, при которой образуется нехватка ресурсов, то есть нескольким стадиям приходится делить один ресурс между собой, из-за чего кому-то приходится ждать, пока он не освободиться, а значит приостанавливать работу). Минимизация таких конфликтов реализуется усовершенствованием структуры устройства
|
||||
- По данным (вызванные зависимостью по данным между несколькими соседними инструкциями). Существует три типа конфликтов по данным:
|
||||
- RAW (read after write — чтение после записи, при котором новая инструкция пытается получить значение из памяти, которая предыдущая инструкция еще не успела туда записать). Разрешается, переброской результата или методом пузырька (приостановкой конвейера)
|
||||
- WAR (write after read — запись после чтения, при котором новая инструкция пытается разместить данные в памяти до того, как старая инструкция успела их оттуда считать). Конфликт возникает в системах с внеочередным исполнением команд, то есть в таких, где заданная программистом последовательность инструкций может быть изменена с целью увеличения производительности. Разрешается конфликт, например, методом пузырька или переименовыванием регистров
|
||||
- WAW (write after write — запись после записи, при котором более ранняя инструкция размещает значение в памяти позже, чем более поздняя инструкция, тем самым нарушая порядок записи в память). Разрешается конфликт так же как и в конфликтах типа WAR.
|
||||
- По управлению (вызванный неоднозначностью того, какая инструкция должна быть загружена после инструкции условного перехода, так как результат перехода будет известен только на стадии Execute, а загружать новую инструкцию надо уже, когда команда условного перехода будет на стадии Decode). Конфликт разрешается методом пузырька, либо предположением о том, произойдет переход или нет. В случае успешного предсказания потери производительности не происходит. В случае неверного предсказания, ступени конвейера, в которые были загружены неправильные команды должны очиститься.
|
||||
|
||||
В среднем, каждая 7 инструкция в программе является инструкцией условного перехода. Поэтому конфликты по управлению сильнее всего влияют на производительность конвейерного процессора.
|
||||
|
||||
Разработанный на лекции конвейерный процессор не устраняет конфликты по управлению, следовательно является недоработанным, функционирует неправильно и рассматривался только в качестве примера.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=NmWBUrUmI3E) на видеозапись лекции
|
||||
2. Пример проектирования конвейерного процессора с похожей архитектурой (MIPS вместо RISC-V) [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера* — весь параграф 7.5]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Еще один пример с конвейером от тех же авторов, но на примере архитектуры ARM [***Харрис и Харрис***. *Цифровая схемотехника и архитектура компьютера. Дополнение по архитектуре ARM —* весь параграф 2.5]
|
||||
2. Тот же разбор MIPS, что из основных материалов, но от отцов RISC и с более подробным обсуждением материала, однозначно очень полезно для ознакомления. И рисунков там больше [***Паттерсон и Хеннесси***. *Архитектура компьютера и проектирование компьютерных систем* — параграфы 4.5 — 4.8]
|
75
Lectures/11. Pipeline hazards.md
Normal file
75
Lectures/11. Pipeline hazards.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Лекция 11. Конфликты конвейерных систем
|
||||
|
||||
Конвейерный процессор обладает большей производительностью, чем однотактная и многотактная реализация, при прочих равных условиях. Для достижения максимальной производительности необходимо, чтобы конвейер не простаивал и был полностью заполнен инструкциями, что является нетривиальной задачей, так как в таком устройстве могут возникать конфликты.
|
||||
|
||||

|
||||
|
||||
Говорят, что возник **структурный конфликт**, если конвейер пришлось приостановить из-за нехватки какого-то ресурса. Как правило это связано либо с недостаточной конвейеризированностью операционных устройств, либо из-за ожидания доступа к памяти при одновременном обращении к ней с нескольких ступеней.
|
||||
|
||||
Говорят, что возник **конфликт по данным**, если порядок чтения или записи операндов отличается от порядка в неконвейерной машине. Проще говоря, если возникает ситуация, что какая-то команда пытается считать операнд, который еще не записан или записать на то место, откуда ещё не успели считать.
|
||||
|
||||
**Конфликт по управлению** возникает, когда приходит команда условного перехода и пока эта команда не выполнится, сохраняется неопределенность какую команду загружать следующей на исполнение (как будто условие сработало или нет?).
|
||||
|
||||
Производительность конвейера напрямую зависит от блока устранения конфликтов — части устройства управления, которая следит за ходом выполнения программы и оперативно определяет и устраняет образовавшиеся конфликты.
|
||||
|
||||
Для того, чтобы обнаружить конфликт по данным применяются так называемые критерии Бернштейна — для двух подряд идущий инструкций k и k+1 проверяются адреса считываемых входных операндов и адреса записываемых выходных результатов, если существует пересечение этих множеств, то можно заключить, что существует зависимость (конфликт) по данным.
|
||||
|
||||
> output(k) & input(k+1) != 0 -> Конфликт чтение после записи (RAW)
|
||||
> input(k) & output(k+1) != 0 -> Конфликт запись после чтения (WAR)
|
||||
> output(k) & output(k+1) != 0 -> Конфликт запись после записи (WAW)
|
||||
|
||||
Для того, чтобы минимизировать влияние подобного конфликта применяются различные методы, среди которых:
|
||||
|
||||
- Метод пузырька (то есть, обнулять стадии конвейера, которые приводят к конфликту, пока он не будет разрешён)
|
||||
- Пересылка результата (то есть, при возникновении конфликта не дожидаться, когда данные дойдут до стадии записи в память, а пересылать их на более ранние стадии конвейера, где они требуются, с более поздних стадий, где эти данные уже получены)
|
||||
- Внеочередное исполнение команд (то есть, ввести специальную аппаратуру, которая в автоматическом режиме будет менять последовательность инструкций так, чтобы конфликты разрешались, но при этом логика работы программы не была нарушена)
|
||||
- Переименовывание регистров (то есть, ввести дополнительные теневые регистры, которые не доступны программисту, но в которых будут сохраняться некоторые результаты операций, чтобы устранить конфликты WAR и WAW)
|
||||
- Сортировка команд на этапе компиляции (статический метод разрешения конфликта, при котором компилятор пытается расположить максимально далеко друг от друга инструкции, которые могут вызвать конфликт)
|
||||
|
||||
Конфликты по управлению влияют на производительность конвейера больше всего, так как по статистике, примерно, каждая седьмая инструкция является инструкцией условного перехода. Другими словами, в среднем, такой конфликт будет возникать раз в семь тактов.
|
||||
|
||||
Для сокращения задержек, вызванных появлением условного перехода применяют следующие подходы:
|
||||
|
||||
- Вычисление исполнительного адреса перехода на ступени декодирования команды, с целью максимально быстрой загрузки инструкции по этому адресу
|
||||
- Использование буфера адресов переходов (branch target buffer – BTB), специальной памяти в которой сохраняются адреса переходов уже вычисленных инструкций условного перехода, чтобы при повторном их исполнении адрес перехода уже был известен и его не надо было вычислять
|
||||
- Кэш-память для хранения команд, расположенных в точке перехода (BTBI). То же самое, что и BTB, но сохраняется не адрес перехода, а инструкция, располагающаяся по целевому адресу
|
||||
- Использование буфера цикла (специальная аппаратура, запоминающая количество итераций цикла, для успешного предсказания результата условного перехода, реализующего выход из цикла)
|
||||
|
||||
Для минимизации конфликтов по управлению, при считывании очередной инструкции условного перехода, делается предположение о том, произойдёт переход или нет. В случае успешного предсказания в конвейер загружается правильная инструкция, тогда производительность не падает. В случае неуспешного предсказания все стадии конвейера, куда успели попасть инструкции из неправильной ветки, очищаются — производительность конвейера снижается.
|
||||
|
||||
Можно выделить два основных подхода к предсказанию условного перехода: статический (предположение делается ещё до исполнения программы) и динамический (предположение делается автоматически, прямо во время исполнения программы, на основе собранной статистики переходов).
|
||||
|
||||
Эффективность статических методов колеблется в больших диапазонах от 50 до 90% успешных предсказаний. Среди таких методов:
|
||||
|
||||
- Переход происходит всегда
|
||||
- Переход не происходит никогда
|
||||
- Предсказание определяется по результатам профилирования (компилятор запускает программу с сырыми данными и фиксирует направления переходов, размещая в специальных полях инструкции результат предсказания)
|
||||
- Предсказание зависит от направления перехода
|
||||
|
||||
Обычно статические методы используются в связке с динамическими, которые собирают статистику переходов в реальном времени и на основе этой статистики делают предположение о переходе. В основе динамических методов лежат несколько подходов к накоплению информации (статистики) о совершенных переходах.
|
||||
|
||||
PHT (pattern hystory table) — специальная память, состоящая из двухбитных ячеек памяти, доступ к которым происходит по некоторому паттерну. Если условный переход происходит, то значение ячейки памяти из PHT закреплённой за этим условным переходом, увеличивается на 1 (но не больше максимального значения 11). Если переход не происходит, то уменьшается на 1 (но не меньше минимального значения 00). Предсказанием является старший из этих двух бит, если он 1, то делается предсказание, что переход произойдёт, если он равен 0, то делается предположение, что он не произойдёт.
|
||||
|
||||
GHR (global history register) — регистр глобальной истории, являющийся сдвиговым регистром некоторой длинны, сдвигающий данные каждый раз, когда поступает на исполнение инструкция условного перехода, при этом в регистр задвигается 1, если переход произошёл, и 0, если нет. Таким образом регистр хранит историю результатов переходов последних n (разрядность регистра) инструкций условного перехода.
|
||||
|
||||
LHR (local history register) — регистр локальной истории. По сути, то же самое, что и GHR, только таких сдвиговых регистров много и они хранят историю конкретных условных переходов.
|
||||
|
||||
PHT, GHR и LHR применяются в устройствах предсказания переходов (branch predictor unit). Все многообразие реализаций предсказателей переходов можно условно разделить на 4 категории:
|
||||
|
||||
1. Одноуровневые (бимодальные). Такие устройства используют в качестве паттерна (адреса) для PHT значение счётчика команд PC. Тогда для каждого условного перехода будет накапливаться статистика, по принципам заложенным в PHT. Чаще используется только часть адреса, чтобы была не очень большая PHT. В таком случае статистика может накладываться друг на друга от разных переходов, это называется alliassing, как показывают исследования он положительно влияет на результаты предсказания.
|
||||
2. Двухуровневые (коррелированные). В таких устройствах тоже используется PHT, но в качестве паттерна (адреса) используется GHR или часть его бит. Либо один из регистров LHR может быть паттерном для PHT. Так же хорошо зарекомендовали себя коррелированные предсказатели, использующие в качестве паттерна для PHT объединение GHR и PC, например, операцией конкатенации (объединения части бит из одного, и части бит от другого) или Исключающего ИЛИ.
|
||||
3. Гибридные. Такие устройства объединяют в себе несколько предикторов (предсказателей) с разной архитектурой и разными характеристиками. Выбор итогового предсказания из всех предсказателей осуществляется по мажоритарной схеме — кто меньше ошибался, тому и верим.
|
||||
4. Ассиметричные. Тоже самое, что и гибридные, но для каждого из предикторов используются собственные PHT, то есть ведётся независимая статистика между всеми предсказателями. Выбор также ведётся по мажоритарной схеме.
|
||||
|
||||
Для обеспечения приемлемого снижения производительности при ошибочном предсказании перехода и, как следствие — очищение конвейера, эффективность предсказания должна соответствовать порядка 97%.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=QvPsKVPO8SU) на видеозапись лекции
|
||||
2. Один из немногих и пожалуй самый объёмный материал по этому вопросу на русском языке, так что выбирать не приходится. Разбираются методы минимизации конфликтов конвейера на уровне структурной организации и на уровне лежащих в решении этой задачи идей [***Орлов и Цилькер***. *Организация ЭВМ и систем* — Глава 9. начиная с параграфа 'Конфликты в конвейере команд', до параграфа (и включая его) 'Динамическое предсказание переходов']
|
||||
3. Более краткий вариант предыдущего источника можно найти в старых лекциях [***Кафедра ВТ***. *Микропроцессорные средства и системы* — Лекция 2.3 и 2.4]
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
||||
|
||||
1. Несколько примеров устранения конфликтов по данным и управлению в контексте архитектуры RISC-V, правда на английском языке, можно найти в этой книге [***Patterson и Hennessy***. *Computer organization and design RISC-V edition* — параграфы 4.7, 4.8]
|
||||
2. Ещё один источник для заинтересованных, тоже на английском языке, но с более академическим подходом и большим объёмом полезной информации [***Shen и Lipasti***. *Modern processor design* — Глава 2]
|
144
Lectures/12. Productivity techniques.md
Normal file
144
Lectures/12. Productivity techniques.md
Normal file
@@ -0,0 +1,144 @@
|
||||
# Лекция 12. Методы повышения производительности
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 12. Методы повышения производительности](#лекция-12-методы-повышения-производительности)
|
||||
- [Содержание](#содержание)
|
||||
- [Суперскалярный процессор](#суперскалярный-процессор)
|
||||
- [Внеочередное выполнение команд](#внеочередное-выполнение-команд)
|
||||
- [Переименование регистров](#переименование-регистров)
|
||||
- [Переупорядочивание команд](#переупорядочивание-команд)
|
||||
- [Централизованное окно команд](#централизованное-окно-команд)
|
||||
- [Распределенное окно команд (алгоритм Томасуло)](#распределенное-окно-команд-алгоритм-томасуло)
|
||||
- [Восстановление последовательности](#восстановление-последовательности)
|
||||
- [Параллелизм](#параллелизм)
|
||||
- [Многопоточность](#многопоточность)
|
||||
- [Пакованная арифметика](#пакованная-арифметика)
|
||||
- [Классификация Флинна](#классификация-флинна)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
|
||||
В последних лекциях разрабатывалось три микроархитектуры:
|
||||
|
||||
- **Однотактный процессор** - каждая инструкция выполняется за один такт, относительно простая для понимания архитектура, но тк каждая инструкция выполняется в течение одного такта нужно ориентироваться на инструкцию с наибольшим критическим путем, поэтому данное решение не является оптимальным.
|
||||
|
||||
- **Многотактный процессор** - одна инструкция выполняется за несколько тактов, причем такты более короткие, тк меньше критический путь, но из всех архитектур является самой не производительной.
|
||||
|
||||
- **Конвейерный процессор** - может обрабатывать несколько инструкций одновременно, имеет короткий критический путь, по сравнению с однотактной архитектурой, но страдает от конфликтов, которые были разобраны подробно в предыдущих лекциях.
|
||||
|
||||
## Суперскалярный процессор
|
||||
|
||||

|
||||
|
||||
Обычный, **скалярный процессор** - процессор который работает с одной порцией данных за одну инструкцию.
|
||||
|
||||
**Суперскалярный процессор** - процессор, поддерживающий так называемый _параллелизм на уровне инструкций_ (процессор способен исполнять из одного общего потока инструкций сразу несколько штук) за счет включения в состав его вычислительного ядра нескольких одинаковых исполнительных устройств.
|
||||
|
||||
Помимо суперскалярных процессоров существуют еще и **Векторные процессоры** - за раз выполняющие одну инструкцию, но ее операндами выступают упорядоченные массивы данных - векторы.
|
||||
|
||||
Пример:
|
||||
|
||||
При максимальной загрузке двухканального суперскалярного процессора и идеальной пропускной способности параметр cpi = 0.5 (cycle per instruction) или ipc = 2 (instruction per cycle). Но на практике идеальных суперскалярных процессоров не бывает.
|
||||
|
||||
Поэтому для увеличения загрузки суперскалярного процессора применяются **различные подходы**.
|
||||
|
||||
### Внеочередное выполнение команд
|
||||
|
||||
Внеочередное исполнение описывает исполнение машинных инструкций не в порядке поступления, а по мере готовности к их выполнению. Упрощенно говоря, при внеочередном исполнении, процессор помещает поступающие команды в очередь по порядку и начинает ожидать выполнения всех условий, для обработки этих команд.
|
||||
Внеочередное выполнение тем эффективнее, чем длиннее конвейер процессора, и чем больше разница между скоростью работы памяти (оперативной или кэшем) и скоростью работы процессора.
|
||||
В современных компьютерах процессоры работают намного быстрее памяти, поэтому во время ожидания поступления данных процессор может выполнить множество инструкций, операнды которых доступны.
|
||||
Проблема: при неупорядоченном исполнении в регистрах могут быть
|
||||
“устаревшие” или “опережающие” значения (конфликты WAW/WAR).
|
||||
|
||||
### Переименование регистров
|
||||
|
||||
Переименование регистров — метод ослабления взаимозависимостей команд, применяемый в процессорах с внеочередным исполнением команд.
|
||||
В том случае, если в соответствии с двумя или более командами необходимо осуществить запись данных в один регистр, их корректное внеочередное исполнение становится невозможным (более поздняя команда не может быть обработана до завершения более ранней) даже в том случае, если при этом нет зависимости по данным. Такие взаимозависимости часто называют ложными (в случае истинной зависимости существует зависимость и по данным).
|
||||
Переименование регистров представляет собой преобразование программных ссылок на архитектурные регистры в ссылки на физические регистры и позволяет ослабить влияние ложных взаимозависимостей за счёт использования большого количества физических регистров вместо ограниченного количества архитектурных
|
||||
|
||||
### Переупорядочивание команд
|
||||
|
||||
После декодирования команд и переименования регистров команды передаются на исполнение. Как уже отмечалось, выдача команд в функциональные блоки может производиться неупорядоченно, по мере готовности. Поскольку порядок выполнения команд может отличаться от предписанного программой, необходимо обеспечить корректность их операндов (частично решается путем переименования регистров) и правильную последовательность занесения результатов в регистры. Одним из наиболее распространенных приемов решения этих проблем служит переупорядочивание команд. В его основе лежат использование окна команд — буферной памяти, куда помещаются все команды, прошедшие декодирование, и переименование регистров (последняя операция выполняется только с теми командами, которые записывают свои результат в регистры). Окно команд обеспечивает отсрочку передачи команд на исполнение до момента готовности операндов, а также нужную очередность завершения команд и загрузки их результатов в регистры.
|
||||
Существует два подхода к реализации окна команд:
|
||||
|
||||
- **Централизованное окно команд**
|
||||
- **Распределенное окно команд** (алгоритм Томасуло)
|
||||
|
||||
### Централизованное окно команд
|
||||
|
||||

|
||||
|
||||
Централизованное окно команд (Scoreboard) представляет собой буферное запоминающее устройство, в котором хранится некоторое количество последних извлеченных из памяти и декодированных команд, а также текущая информация о доступности ресурсов, привлекаемых для их исполнения. Функциями табло являются оперативное выявление команд, для исполнения которых уже доступны все необходимые операнды и ресурсы, и выдача таких команд на исполнение в соответствующие функциональные блоки. Табло можно рассматривать как систему предварительной диспетчеризации команд, однако оно осуществляет контроль выполнения команд и после их выдачи.
|
||||
|
||||

|
||||
|
||||
Все извлеченные из памяти команды сразу же после их декодирования и (если это необходимо) переименования регистров заносятся в табло, причем с соблюдением порядка их следования в программе. Физически табло реализуется на основе ассоциативной памяти. Каждой команде выделяется одна ячейка, состоящая из нескольких полей:
|
||||
|
||||
- поля операции, где хранится дешифрированный код операции;
|
||||
- поля результата;
|
||||
- двух поля операндов (значение или идентификатор);
|
||||
- поля битов достоверности (соответствуют каждому из операндов и показывают доступно ли его значение )
|
||||
- текущая информация о доступности устройств обработки (функциональных блоков).
|
||||
|
||||
### Распределенное окно команд (алгоритм Томасуло)
|
||||
|
||||

|
||||
|
||||
В варианте распределенного окна команд на входе каждого функционального блока размещается буфер декодированных команд, называемый накопителем команд или схемой резервирования (reservation station). После выборки и декодирования команды распределяются по схемам резервирования тех функциональных блоков, где команда будет исполняться. В буфере команда запоминается и по готовности выдается в связанный с данным пунктом функциональный блок. Логика работы каждого накопителя аналогична централизованному окну команд. Выдача происходит только после того, как команда получит все необходимые операнды, и при условии, что функциональный блок свободен. При обновлении содержимого буфера переименования файла производится доступ ко всем накопителям команд, и в них идентификаторы обновленных входов заменяются хранящимися в этих входах значениями операндов.
|
||||
|
||||
### Восстановление последовательности
|
||||
|
||||

|
||||
|
||||
**Буфер восстановления последовательности** (БВП) — это универсальный инструмент для поддержания правильной последовательности исполнения команд в случае нескольких параллельно работающих функциональных блоков.
|
||||
|
||||
БВП представляет собой кольцевой буфер с указателями головной и хвостовой части. Указатель головной части содержит адрес, следующего свободного входа. Команды заносятся в БВП в порядке, определяемом программой. Каждая выданная команда помещается в следующую свободную ячейку буфера (говорят, что команде выделен очередной свободным вход БВП.), причем выделение ячеек идет с соблюдением последовательности выдачи команд. Каждый занятый вход содержит также информацию о состоянии хранимой в нем команды: команда только выдана (i), находится в стадии исполнения (х) или уже завершена (f). Указатель хвостовой части показывает па команду, подлежащую удалению из БВП прежде других. Удаление команды разрешено, только если она завершена и предшествующие ей команды уже удалены из буфера. Этот механизм гарантирует что команды покидают БВП строго по порядку. Очередность выполнения команд программы сохраняется благодаря тому, что заносить свои результаты в память или регистры разрешается лишь тем командам, которые покинули БВП.
|
||||
|
||||
Название буфера подчеркивает его основную задачу — поддержание строгой последовательности завершения команд путем переупорядочивания тех из них, которые исполнялись с нарушением этой последовательности. Однако БВП более универсален - с равным успехом он годится и для переименования регистров, и для распределения декодированных команд по накопителям (схемам резервирования).
|
||||
|
||||
## Параллелизм
|
||||
|
||||
Рассмотрим виды параллелизма:
|
||||
|
||||
- Временной
|
||||
- Пространственный
|
||||
|
||||
Не смотря на то, что конвейерный процессор за один так выдает результат лишь одной инструкции, на каждом такте в процессе выполнения находятся несколько инструкций одновременно, но на разных стадиях. Это и называется **временным параллелизмом**.
|
||||
|
||||
Примером **пространственного параллелизма** может служить принцип работы _суперскалярного процессора_, т.к. за счет наличия одинаковых функциональных устройств на них одновременно могут выполняться различные инструкции.
|
||||
|
||||
Не стоит путать и следующие два вида параллелизма:
|
||||
|
||||
- Instruction Level Parallelism (ILP) - параллелизм уровня команд (рассмотрен в суперскалярном процессоре)
|
||||
- Thread Level Parallelism (TLP) - параллелизм уровня потоков (когда две программы работают параллельно, используя разные потоки)
|
||||
|
||||
Следует понимать, что суперскалярный процессор повышает производительность тем, что выполняет параллельно несколько инструкций одной программы, то есть обладает _параллелизмом уровня команд_ (ILP).
|
||||
А многоядерный процессор - тем, что выполняет независимо два (или более) потока инструкций, то есть обладает _параллелизмом уровня потоков_ (TLP).
|
||||
|
||||
## Многопоточность
|
||||
|
||||
**Многопоточность** - свойство платформы (например, операционной системы) или приложения, состоящее в том, что процесс, порождённый в операционной системе, может состоять из нескольких потоков, выполняющихся «параллельно», то есть без предписанного порядка во времени. При выполнении некоторых задач такое разделение может достичь более эффективного использования ресурсов вычислительной машины. Такие потоки называют также потоками выполнения (thread of execution).
|
||||
|
||||
На обычном процессоре управление потоками осуществляется операционной системой. Поток исполняется до тех пор, пока не произойдёт аппаратное прерывание, системный вызов или пока не истечёт отведённое для него операционной системой время. После этого процессор переключается на код операционной системы, который сохраняет состояние потока (его контекст) или переключается на состояние другого потока, которому тоже выделяется время на исполнение. При такой многопоточности достаточно большое количество тактов процессора тратится на код операционной системы, переключающий контексты. Если поддержку потоков реализовать аппаратно, то процессор сам сможет переключаться между потоками. Для такой реализации достаточно добавить еще один счетчик PC (program counter) и еще один регистровый файл.
|
||||
|
||||
Важно учесть, что **многопоточность не повышает параллелизм уровня команд (ILP)**, но повышает пропускную способность конвейера.
|
||||
|
||||
## Пакованная арифметика
|
||||
|
||||

|
||||
|
||||
**Пакованная арифметика** - способ выполнения нескольких однотипных операции за одну инструкцию за счет "склеивания" нескольких чисел. Пример: на 32 битном АЛУ при помощи пакованной арифметики можно произвести сложение 4-х пар 8-битных чисел за одну операцию, вместо того чтобы производить 4 сложения.
|
||||
|
||||
## Классификация Флинна
|
||||
|
||||
**Классификация Флинна** — общая классификация архитектур ЭВМ по признакам наличия параллелизма в потоках команд и данных. Была предложена Майклом Флинном в 1966 году и расширена в 1972 году.
|
||||
|
||||
В ней машины разделяют на группы:
|
||||
|
||||
- SISD (single instruction single data)
|
||||
- SIMD (single instruction multiple data) - Векторные процессоры
|
||||
- MISD (multiple instruction single data)
|
||||
- MIMD (multiple instruction multiple data)
|
||||
|
||||
### Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=deTK5ZjFWaw) на видеозапись лекции
|
143
Lectures/13. Processor architecture classification.md
Normal file
143
Lectures/13. Processor architecture classification.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# Лекция 13. Виды и классификация архитектур
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 13. Виды и классификация архитектур](#лекция-13-виды-и-классификация-архитектур)
|
||||
- [Содержание](#содержание)
|
||||
- [Архитектура](#архитектура)
|
||||
- [Классификация архитектур](#классификация-архитектур)
|
||||
- [Классификация архитектур по способу хранения операндов](#классификация-архитектур-по-способу-хранения-операндов)
|
||||
- [Классификация архитектур по составу и сложности команд](#классификация-архитектур-по-составу-и-сложности-команд)
|
||||
- [Классификация архитектур по способу реализации условных переходов](#классификация-архитектур-по-способу-реализации-условных-переходов)
|
||||
- [Классификация инструкций](#классификация-инструкций)
|
||||
- [Классификация инструкций по функциональному назначению](#классификация-инструкций-по-функциональному-назначению)
|
||||
- [Классификация инструкций по способу адресации операндов](#классификация-инструкций-по-способу-адресации-операндов)
|
||||
- [Классификация инструкций по количеству операндов в инструкции](#классификация-инструкций-по-количеству-операндов-в-инструкции)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
|
||||
## Архитектура
|
||||
|
||||
**Архитектура** - абстрактная модель функциональных возможностей процессора (средства, которыми может пользоваться программист)
|
||||
|
||||
_Строгое определение:_
|
||||
|
||||
**Архитектура набора команд** (Instruction set architecture) включает в себя два понятия:
|
||||
|
||||
- Система команд (инструкции аппаратно реализуемые в процессоре)
|
||||
- Средства для выполнения команд:
|
||||
- форматы данных
|
||||
- системы регистров
|
||||
- способы адресации
|
||||
- модели памяти
|
||||
|
||||
## Классификация архитектур
|
||||
|
||||
### Классификация архитектур по способу хранения операндов
|
||||
|
||||
- **Аккумуляторная архитектура**
|
||||
Архитектура на базе аккумулятора исторически возникла одной из первых. В ней для хранения одного из операндов арифметической или логической операции в процессоре имеется выделенный регистр — аккумулятор. В этот же регистр заносится и результат операции. Поскольку адрес одного из операндов предопределен, в командах обработки достаточно явно указать местоположение только второго операнда. Изначально оба операнда хранятся в основной памяти, и до выполнения операции один из них нужно загрузить в аккумулятор. После выполнения команды обработки результат находится в аккумуляторе и, если он не является операндом для последующей команды, его требуется сохранить в ячейке памяти.
|
||||
|
||||
- **Регистровая архитектура**
|
||||
В машинах данного типа процессор включает в себя массив регистров (регистровый файл), известных как регистры общего назначения. Эти регистры можно рассматривать как явно управляемый кэш для хранения недавно использовавшихся данных.
|
||||
Регистровая архитектура допускает расположение операндов в одной из двух запоминающих сред: основной памяти или регистрах.
|
||||
|
||||
- **Load/store архитектура**
|
||||
Load/store архитектура представляет собой архитектуру набора команд, которая делит инструкции на две категории: доступ к памяти (загрузка и сохранение между памятью и регистрами) и операции ALU (которые происходят только между регистрами).
|
||||
|
||||
- **Стековая архитектура**
|
||||
В вычислительных машинах, где реализована архитектура на базе стека, операнды выбираются из двух верхних ячеек стековой памяти. Результат операции заносится в вершину стека.
|
||||
|
||||
### Классификация архитектур по составу и сложности команд
|
||||
|
||||
**CISC** (complex instruction set computer)
|
||||
Архитектура с полным набором команд (относится к регистровой архитектуре набора команд)
|
||||
|
||||
**Особенности**:
|
||||
|
||||
- Имеет большое количество различных команд, каждая из которых выполняется несколько тактов
|
||||
- Устройство управления с программируемой логикой
|
||||
- Небольшое количество регистров общего назначения
|
||||
- Различные форматы команд с разной длиной
|
||||
- Преобладание двухадресной адресации
|
||||
- Развитый механизм адресации операндов, включающий различный методы косвенной адресации
|
||||
|
||||
---
|
||||
|
||||
**RISC** (reduced instruction set computer)
|
||||
Архитектура с сокращенным набором команд (относится к load/store архитектуре набора команд).
|
||||
|
||||
**Особенности**:
|
||||
|
||||
- Большая часть команд выполняется за один такт
|
||||
- Стандартная однословная длина всех команд, равная естественной длине слова и ширине шины данных и допускающая унифицированную конвейерную обработку всех команд
|
||||
- Малое число стандартных команд (не более 128)
|
||||
- Малое количество форматов команд (не около 4)
|
||||
- Малое число способов адресации (не более 4)
|
||||
- Доступ к памяти только посредством команд чтения и записи (load/store)
|
||||
- Все команды, кроме чтения и записи, используют внутрипроцессорные межрегистровые пересылки
|
||||
- Устройство управления с аппаратной (жесткой) логикой
|
||||
|
||||
---
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
**VLIW** (very long instruction word)
|
||||
|
||||

|
||||
|
||||
Архитектура с длинным командным словом (грубо говоря, объединение нескольких RISC процессоров работающих параллельно).
|
||||
|
||||
**Особенности**:
|
||||
|
||||
- Сложный регистровый файл, усложненные связи с вычислительными устройствами
|
||||
- Большой объем программного кода
|
||||
- Невозможность миграции программ, написанных под другие архитектуры
|
||||
- Сложность отладки
|
||||
|
||||
---
|
||||
|
||||
### Классификация архитектур по способу реализации условных переходов
|
||||
|
||||
- Переход происходит или не происходит исходя из значений _флагов_, формируемых операционными устройствами
|
||||
|
||||
- Специальные операции меняют содержимое _регистра состояний_ (state register). Команда условного перехода происходит, если содержимое регистра состояний соответствует выполняемой инструкции
|
||||
|
||||
## Классификация инструкций
|
||||
|
||||
### Классификация инструкций по функциональному назначению
|
||||
|
||||
- **Инструкции работы с данными**
|
||||
- Перемещение данных
|
||||
- Модификация данных
|
||||
- Арифметические
|
||||
- Логические
|
||||
- Сдвига
|
||||
- Сравнения
|
||||
|
||||
- **Инструкции управления**
|
||||
- Управление программой
|
||||
- Условный переход
|
||||
- Безусловный переход
|
||||
- Управления процессором
|
||||
|
||||
### Классификация инструкций по способу адресации операндов
|
||||
|
||||
- Непосредственная (операнд содержится внутри инструкции)
|
||||
- Прямая (указывается адрес операнда в основной памяти)
|
||||
- Регистровая (указывается адрес регистра в регистровом файле)
|
||||
- Косвенно-регистровая (указывается адрес регистра, в кортом лежит адрес операнда в основной памяти)
|
||||
- Косвенно-регистровая со смещением (указывается адрес регистра, в котором лежит базовый адрес, к которому прибавляется константа из инструкции, полученное число является адресом операнда в основной памяти)
|
||||
- Относительная (является суммой регистра специального назначения и константы)
|
||||
|
||||
### Классификация инструкций по количеству операндов в инструкции
|
||||
|
||||
- 0 - Нет операндов
|
||||
- 0 - Подразумеваемый операнд
|
||||
- 1 - один операнд
|
||||
- 2 - два операнда
|
||||
|
||||
### Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=w4KbkQSDJLU) на видеозапись лекции
|
274
Lectures/14. Interrupt subsystem.md
Normal file
274
Lectures/14. Interrupt subsystem.md
Normal file
@@ -0,0 +1,274 @@
|
||||
# Лекция 14. Подсистема прерывания
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 14. Подсистема прерывания](#лекция-14-подсистема-прерывания)
|
||||
- [Содержание](#содержание)
|
||||
- [Определение](#определение)
|
||||
- [Сканирование-входов](#сканирование-входов)
|
||||
- [Передача управления при прерывании](#передача-управления-при-прерывании)
|
||||
- [Классификация событий прерывания](#классификация-событий-прерывания)
|
||||
- [Основные характеристики прерываний](#основные-характеристики-прерываний)
|
||||
- [Допустимые моменты прерывания программы](#допустимые-моменты-прерывания-программы)
|
||||
- [Маски́рование прерывания](#маски́рование-прерывания)
|
||||
- [Способы выявления прерывания](#способы-выявления-прерывания)
|
||||
- [Схемы реализации контроллера прерываний](#схемы-реализации-контроллера-прерываний)
|
||||
- [Контроллер прерывания](#контроллер-прерывания)
|
||||
- [Control and Status Register RISC-V](#control-and-status-register-risc-v)
|
||||
- [Подсистема прерываний для RISC-V](#подсистема-прерываний-для-risc-v)
|
||||
- [Программа, реализующая прерывания на ассемблере](#программа-реализующая-прерывания-на-ассемблере)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
- [Дополнительные материалы к лекции для саморазвития](#дополнительные-материалы-к-лекции-для-саморазвития)
|
||||
|
||||
## Определение
|
||||
|
||||
**Прерывание** — событие, на которое реагирует процессор.
|
||||
|
||||
_Пример_: Перемещение мыши. Если бы не было прерываний, то процессор был бы вынужден постоянно обращаться к мыши с целью узнать: изменилось ли её положение или нет, стоит ли перерисовать курсор. А это очень ресурсоёмко. Такой подход называется [сканирование входов](#сканирование-входов).
|
||||
|
||||
### Сканирование-входов
|
||||
|
||||
**Сканирование входов** — последовательный программный опрос входных сигналов. Этот подход используется в суперкомпьютерах, т.к. у них неразвитая периферия. В таком случае подсистема прерываний не нужна.
|
||||
|
||||
## Передача управления при прерывании
|
||||
|
||||
В случае, если во время выполнения программы произошло событие прерывания, процессор останавливает выполнение основной программы и начинает выполнять подпрограмму обработки прерывания. Завершив обработку прерывания, процессор возвращается к исполнению основной программы.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Схема передачи управления при прерывании.*
|
||||
|
||||
## Классификация событий прерывания
|
||||
|
||||
- **Прерывания** — события, сигнал о которых приходит извне. Это события происходит _асинхронно_ фронту тактового импульса. Пример: перемещение мыши.
|
||||
- Маски́руемые — прерывания, которые процессор может игнорировать. _Например_: нажатие клавиши на клавиатуре. [Аппаратная реализация]( #маски́рование-прерывания) будет продемонстрирована чуть позже.
|
||||
- Немаски́руемые — прерывания, которые процессор не может игнорировать. _Например_: сигнал от датчика температуры о перегреве процессора.
|
||||
- **Исключения** — события, происходящие вследствие выполнения какой-то инструкции. Эти события происходят _синхронно_ фронту тактового импульса.
|
||||
- Ошибки. _Например_: обращение в несуществующую область памяти.
|
||||
- Ловушки. _Например_: деление на 0.
|
||||
- Отказы. _Например_: ситуации, которые никак нельзя устранить. Зачастую приводят к выключению/перезапуску процессора.
|
||||
|
||||
## Основные характеристики прерываний
|
||||
|
||||
- **Время реакции прерывания**, T<sub>реакции</sub>
|
||||
|
||||
Это время, между запросом на прерывание и переходом к прерывающей программе (см. рис. 2)
|
||||
|
||||
- **Затраты времени на переключение программ**, T<sub>загрузки</sub> и T<sub>востановления</sub>
|
||||
|
||||
Это время, которое требуется программе выполнить сервисные инструкции (см. рис. 2). Например: узнать причину прерывания, сохранить данные на стек прерывания и др.
|
||||
|
||||
- **Эффективность прерывания**
|
||||
|
||||
Это время эффективной работы программы. Т.е. отношение "полезных" (не сервисных) инструкций программы прерывания ко всем инструкциям прерывания.
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Характеристики прерывания.*
|
||||
|
||||
- **Глубина прерывания**
|
||||
|
||||
Это кол-во прерываний, которые могут произойти во время обработки прерывания (см. рис. 3). Например: если процессор, находясь внутри прерывания, не способен прерваться на другое, то говорят что глубина прерывания n=1. Также программы могут неограниченно прерывать друг друга, в таком случаем, есть ограничение по памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Глубина прерываний.*
|
||||
|
||||
## Допустимые моменты прерывания программы
|
||||
|
||||
В зависимости от архитектуры процессора могут быть использованы различные методы, определяющие когда прерывание становится возможным:
|
||||
|
||||
- **Метод помеченного оператора**
|
||||
|
||||
Внутри какой-нибудь инструкции добавляется бит, отвечающий за прерывание. Допустим, если этот бит равен 1 и есть сигнал на прерывание, то процессор запустит обработчик прерывания.
|
||||
|
||||
- **Покомандный метод**
|
||||
|
||||
Этот метод относится к [многотактным архитектурам](09.%20Multicycle%20processor.md). Процессор начинает реагировать на сигнал прерывания, только после завершения инструкции.
|
||||
|
||||
- **Метод быстрого реагирования**
|
||||
|
||||
Этот метод позволяет реагировать на прерывание на любом такте.
|
||||
|
||||
### Маски́рование прерывания
|
||||
|
||||
**Маска прерывания** — это регистр, отвечающий за разрешение на прерывание (см. рис. 4). Эта маска побитово перемножается с запросами на прерывание других устройств/модулей. Если в результате перемножения получилась хотя бы одна 1, то формируется сигнал `interrupt`, который подаётся на блок управления процессора.
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Аппаратная реализация маски́рования прерывания.*
|
||||
|
||||
## Способы выявления прерывания
|
||||
|
||||
- **Обзорная система прерывания**
|
||||
|
||||
Каждый запрос на прерывание запускает одну и ту же подпрограмму, которая определяет, кто отправил запрос, а затем запускает конкретную программу обработчика прерывания. Работает такая система сравнительно дольше, но реализация её проще.
|
||||
|
||||
- **Векторная система прерывания**
|
||||
|
||||
В векторной системе есть участок памяти — _таблица векторов прерывания_. В таблице лежат **вектора прерывания** — адрес начала подпрограммы обработчика прерывания. После обращения к таблице будет запущена нужная подпрограмма. Работает такая система быстрее, но реализовать её сложнее.
|
||||
|
||||
## Схемы реализации контроллера прерываний
|
||||
|
||||
[**Контроллер прерывания**](#контроллер-прерывания) — устройство, которое отвечает за передачу сигнала прерывания процессору и формирование кода причины прерывания.
|
||||
|
||||
- **Цепочечная схема**
|
||||
|
||||
От процессора идет сигнал подтверждения `ПДТ`, который приходит только тогда, когда процессор готов обработать какое-то прерывание (см. рис. 5.). Этот сигнал приходит на вход первого устройства, которое, в случае необходимости, выдаёт процессору сигнал на прерывание и вектор прерывания. Если же в прерывании от первого устройства нет необходимости, то сигнал подтверждения передаётся на следующее устройство и т.д. Цепочечная схема проста в реализации, но очень медленная. К тому же в этой схеме некоторые устройства имеют приоритет на другими в очерёдности обработки запроса на прерывание. Также существует вероятность, что до последних устройств никогда не дойдёт сигнал подтверждения, и процессор не обработает их запрос на прерывание.
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Цепочечная схема.*
|
||||
|
||||
- **Схема с циклическим опросом**
|
||||
|
||||
Каждый раз, когда в счётчик `СТ` приходит сигнал `C` (тактирование), он увеличивает своё значение (см рис. 6). Затем это значение подаётся на вход дешифратору `DC`, который только на одном выходе выдаёт 1. И каждый такт меняется номер выхода от 0 до N. Если во время обхода всех выходов появится сигнал на прерывание, то этот сигнал отправится на RS триггер, который затем отправит `interrupt` сигнал процессору. А на вход `C` счётчика `CT` будет отправлен 0. В таком случае счётчик перестанет суммировать, и он будет иметь значение кода номера прерывания.
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Циклическая схема.*
|
||||
|
||||
- **Дейзи-цепочка**
|
||||
|
||||
Рассмотрим дейзи-цепочку (см. рисунок 7). Эта схема будет работать только тогда, когда вход `Приоритет` равен 1. Если на первый запрос пришла 1, то на соответствующий выход y<sub>1</sub> будет подана 1, которая будет говорить о том, что именно первое устройство сделало запрос на прерывание. На выход `INT` также будет передана 1, которая отправится процессору для оповещения о прерывании. На остальные же выходы y<sub>2</sub>...y<sub>n</sub> будет передан 0. Т.е. на выходе y<sub>1</sub>...y<sub>n</sub> будет получена только одна 1 от запроса с наивысшим приоритетом. Дейзи-цепочка часто используется в определении наиболее приоритетного запроса.
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Дейзи-цепочка.*
|
||||
|
||||
### Контроллер прерывания
|
||||
|
||||
Теперь рассмотрим, как выглядит контроллер прерывания. (см. рис. 8) По каналу `ПДТ` поступает сигнал от процессора, разрешающий прерывание. Этот сигнал поступает на регистры запроса прерывания. Затем с помощью [маски прерывания](#маски́рование-прерывания) определяются, каким устройствам разрешён запрос на прерывание. Сигналы на прерывания попадают в `схему определения наиболее приоритетного запроса` (_например_: дейзи-цепочка), где определяется самый приоритетный запрос. С помощью `формирователя номера запроса` формируется некоторое число, отвечающее за степень приоритета запроса. В `схеме сравнения приоритетов` сравнивается это число с приоритетом текущего прерывания (приоритет текущего прерывания записан в регистры `порога прерывания`). Если число, хранимое в регистрах "_порога прерывания_" меньше, то в `порог прерывания` записывается новое число, а на процессор по каналу `ЗП` пойдёт сигнал о новом прерывании.
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Схема контроллера прерывания.*
|
||||
|
||||
## Control and Status Register RISC-V
|
||||
|
||||
Это набор регистров, связанных с блоками процессора, с помощью которых можно управлять ими или узнавать информацию о них.
|
||||
Минимальный набор для поддержания прерывания в RISC-V нужно реализовать следующие регистры:
|
||||
|
||||
| Номер | Привилегия | Имя | Описание |
|
||||
|:------------|:-----------|:----------|:-----------------------------------------------------------|
|
||||
| Ox304 | MRW | mie | Регистр маски |
|
||||
| Ox305 | MRW | mtvec | Регистр вектора прерывания |
|
||||
| Ox340 | MRW | mscratch | Регистр указателя на стек прерывания |
|
||||
| Ox341 | MRW | mepc | Регистр адреса инструкции, на котором случилось прерывание |
|
||||
| Ox342 | MRW | mcause | Регистр причины (кода) прерывания |
|
||||
|
||||
Инструкции для работы с CSR:
|
||||
|
||||
| Opcode | func3 | Тип | Инструкция | Описание | Операция |
|
||||
|:----------|:------|:-----|:--------------------|:--------------------------|:------------------------|
|
||||
| 1110011 | 000 | I | mret | Возврат и прерывание | PC=merc |
|
||||
| 1110011 | 001 | I | csrrw rd, csr, rs1 | Чтение/запись CSR | rd = csr, csr=rs1 |
|
||||
| 1110011 | 010 | I | csrrs rd, csr, rs1 | Чтение/установка бит CSR | rd = csr, csr=rs1\|rs1 |
|
||||
| 1110011 | 011 | I | csrrc rd, csr, rs1 | Чтение/очистка бит CSR | rd=csr, csr=csr&~rs1 |
|
||||
|
||||
## Подсистема прерываний для RISC-V
|
||||
|
||||

|
||||
|
||||
*Рис. 9. Микроархитектура RISC-V с CSR.*
|
||||
|
||||
Теперь рассмотрим отдельно блок CSR:
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Схема CSR.*
|
||||
|
||||
Рассмотрим схему CSR (см. рис. 10). На ней красным прямоугольником (номер 1) отмечены регистры CSR. К нему подключены мультиплексор и демультиплексор для считывания и записи данных с регистров (номер 2 и 3). С помощью входа `A`, определяется к какому регистру будет применена запись/чтение. Теперь рассмотрим нижнюю часть схемы (см. рис. 11):
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Нижняя часть схемы CSR.*
|
||||
|
||||
Она нужна для оперативного обновления значений регистров `mepc` и `mcause`. Вход `OP[2]` — это сигнал о возникновении прерывания. Если сигнал на прерывание равен 1, то значения `mepc` и `mcause` изменятся. Осталось рассмотреть верхнюю часть схемы (см. рис. 12):
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Верхняя часть схемы CSR.*
|
||||
|
||||
Она нужна для реализации инструкций для работы с CSR. В зависимости от нужной инструкции у выхода `WD` будет своё значение. На нулевой вход мультиплексора поступают нули, если не требуется запись в регистры.
|
||||
Отдельно стоит отметить, что значение регистра причины прерывания `mcause` берётся из контроллера прерывания. А значение регистра маски прерывании `mie`, которое мы устанавливаем в блоке CSR, отправляется в контроллер прерывания. Давайте рассмотрим устройство контроллера прерывания. У него будет [схема с циклическим опросом](#схемы-реализации-контроллера-прерываний) (см. рис. 13):
|
||||
|
||||

|
||||
|
||||
*Рис. 13. Контроллер прерывания с циклическим опросом.*
|
||||
|
||||
На вход в контроллер прерывания подаются регистры маски прерывания `mie[31:0]`, запросы на прерывание `int_req[31:0]`. Если бит маски и бит запроса будут равны 1 и если в этот момент времени счётчик (красный прямоугольник на рисунке 13) будет соответствовать данному запросу на прерывание, то счётчик будет заблокирован, и будет сформирован сигнал `INT`, который сообщит о прерывании. Значение регистра `mcause` будет соответствовать значению остановленного счётчика.
|
||||
|
||||
Такое состояние будет, пока не придёт сигнал с `INT_RST`. Также после получения сигнала `INT_RST` периферийному устройству, чей сигнал обрабатывался, будет передана 1 через регистр `int_fin`, сигнализирующий о том, что обработка прерывания окончена.
|
||||
|
||||
В целом схема подключения выглядит так (см. рис. 14):
|
||||
|
||||

|
||||
|
||||
*Рис. 14. Схема подключения подсистемы прерывания.*
|
||||
|
||||
## Программа, реализующая прерывания на ассемблере
|
||||
|
||||
Программа обрабатывает два прерывания, имеющие коды 5 и 19. При пятом прерывании некоторое число из памяти делится на 2. При девятнадцатом прерывании к некоторому числу из памяти прибавляется 3.
|
||||
|
||||
```assembly
|
||||
# Инициализируем начальные значения регистров
|
||||
li sp, 0xFFFFFFFC # устанавливаем указатель на верхушку стека
|
||||
li gp, 0x10000000 # устанавливаем указатель на глобальные данные
|
||||
|
||||
li t0, 0x00080020 # подготавливаем маску прерывания для 5 и 19 входов
|
||||
csrw mie, t0 # загружаем маску в регистр маски
|
||||
la t0, interrupt # аналогично li загружает число, в данном случае - адрес
|
||||
csrw mtvec, t0 # устанавливаем вектор прерывания
|
||||
li t0, 0xEFFFFFFC # готовим адрес верхушки стека прерывания
|
||||
csrw mscratch, t0 # загружаем в указатель на верхушку стека прерывания
|
||||
|
||||
li t0, 1 # начальное значение глобальной переменной
|
||||
lw t0, 0(gp) # загружаем переменную в память
|
||||
|
||||
while: # бесконечный цикл, аналогичный while (1);
|
||||
beq x0, x0, while # ничего не делаем!
|
||||
|
||||
interrupt:
|
||||
csrrw t0, mscratch, t0 # меняем местами mscratch и t0
|
||||
sw t1, 0(t0) # сохраняем t1 на стек mscratch
|
||||
sw t2, 4(t0) # сохраняем t2 на стек mscratch
|
||||
|
||||
# Переключаем адрес возврата на следующую инструкцию
|
||||
csrr t2, mepc # t2 = pc в момент прерывания
|
||||
addi t2, t2, 4 # увеличиваем pc на 4
|
||||
csrw mepc, t2 # mepc = mepc + 4
|
||||
|
||||
# Проверяем регистр причины и на 5-ое прерывание
|
||||
csrr t1, mcause # t1 = mcause
|
||||
li t2, 5 # t2 = 5 (код одного из прерываний)
|
||||
bne t1, t2, nineteen # если это не 5 прерывание, то проверяем 19
|
||||
# Обработчик 5-го прерывания
|
||||
lw t2, 0(gp) # загружаем переменную из памяти
|
||||
addi t2, t2, 3 # прибавляем к значению 3
|
||||
sw t2, 0(gp) # возвращаем переменную в память
|
||||
j done # идем возвращать регистры и на выход
|
||||
|
||||
nineteen: # Проверяем на 19-ое прерывание
|
||||
li t2, 19 # t2 = 19 (код другого прерывания)
|
||||
bne t1, t2, done # если не 19-ое, то выходим
|
||||
# Обработчик 19-го прерывания
|
||||
lw t2, 0(gp) # загружаем переменную из памяти
|
||||
srli t2, t2, 1 # делим число пополам сдвигом вправо
|
||||
sw t2, 0(gp) # возвращаем переменную в память
|
||||
j done # идем возвращать регистры и на выход
|
||||
|
||||
# Возвращаем регистры на места и выходим
|
||||
done:
|
||||
lw t1, 0(t0) # возвращаем t1 со стека
|
||||
lw t2, 4(t0) # возвращаем t2 со стека
|
||||
csrrw t0, mscratch, t0 # меняем обратно местами t0 и mscratch
|
||||
mret # возвращаем управление программе (pc = mepc)
|
||||
|
||||
```
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://youtu.be/E21EtIasiU8?si=f_UEatkkQUow9iX5) на видеозапись лекции
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
179
Lectures/15. Memory.md
Normal file
179
Lectures/15. Memory.md
Normal file
@@ -0,0 +1,179 @@
|
||||
# Лекция 15. Память
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 15. Память](#лекция-15-память)
|
||||
- [Содержание](#содержание)
|
||||
- [Определение](#определение)
|
||||
- [Характеристики](#характеристики)
|
||||
- [Метод доступа к данным](#метод-доступа-к-данным)
|
||||
- [Иерархия памяти](#иерархия-памяти)
|
||||
- [Локальность по обращению](#локальность-по-обращению)
|
||||
- [Статическая и динамическая память](#статическая-и-динамическая-память)
|
||||
- [Регенерация DRAM](#регенерация-dram)
|
||||
- [Сравнение SRAM и DRAM](#сравнение-sram-и-dram)
|
||||
- [Структура микросхемы памяти](#структура-микросхемы-памяти)
|
||||
- [Блочная память](#блочная-память)
|
||||
- [Расслоение памяти](#расслоение-памяти)
|
||||
- [Способы доставки данных](#способы-доставки-данных)
|
||||
- [Энергонезависимая память](#энергонезависимая-память)
|
||||
- [Flash-память](#flash-память)
|
||||
- [Защита памяти](#защита-памяти)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
|
||||
## Определение
|
||||
|
||||
**Система памяти** — это функциональный блок микропроцессорной системы, предназначенный для временного или постоянного хранения данных и команд, состоящий из _запоминающего устройства_ и _устройства управления_.
|
||||
|
||||
## Характеристики
|
||||
|
||||
- **Ёмкость** — это количество битов данных, которые запоминающее устройство может хранить единовременно.
|
||||
- **Единица пересылки** — это количество битов данных, передаваемых по линиям шины одновременно.
|
||||
- **Быстродействие** состоит из нескольких характеристик:
|
||||
- _Время выборки данных_ — это время между началом формирования запроса к памяти и получения первых бит информации на выходах из памяти.
|
||||
- _Время хранения данных_
|
||||
- _Период обращения_ — это минимальное время, которое должно пройти между обращениями к памяти.
|
||||
- _Скорость передачи данных_
|
||||
|
||||
P.S. Стоит отметить, что не существует памяти, которая будет одновременно и ёмкой, и быстрой, и дешёвой в производстве. В любом случаем придётся жертвовать одним из трёх пунктов.
|
||||
|
||||
## Метод доступа к данным
|
||||
|
||||
- **Произвольный** — метод, который просто возвращает данные по указанному адресу (RAM — Randoom Access Memory).
|
||||
- **Последовательный** — метод, при котором перед получением данных нужно прочитать все ячейки памяти, находящиеся до нужного адреса (видеокассета).
|
||||
- **Прямой** — это метод при котором поиск макроячейки осуществляется произвольным методом, а внутри макроячейки осуществляется последовательный поиск нужной ячейки.
|
||||
- **Ассоциативный** — это метод, который поиск осуществляется по тегам (Кэш-память).
|
||||
|
||||
## Иерархия памяти
|
||||
|
||||
С течением времени производительность процессора увеличивалась в разы быстрее чем производительность памяти, вследствие чего память отделилась от процессора и стала отдельным блоком. Из-за этого появилась **иерархия памяти** (см. рис. 1). Память в компьютере состоит из нескольких уровней, которые условно разделены на две части: внутренняя и внешняя. К внутренняя нужна для функционирования системы, а внешняя для хранения больших данных, которые могут быть использованы процессором не так часто.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Иерархия памяти.*
|
||||
|
||||
В иерархии памяти можно выделить несколько зависимостей (см. рис. 2):
|
||||
|
||||
- Чем ближе часть памяти к процессору, тем меньше у неё ёмкость и тем она быстрее работает.
|
||||
- Чем ближе часть памяти к процессору, тем чаще тот к ней обращается.
|
||||
- Чем дальше от процессора, тем дешевле единица памяти. Т.е. гигабайт магнитной ленты стоит во много раз дешевле гигабайта кэш-памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Зависимости в иерархии памяти.*
|
||||
|
||||
### Локальность по обращению
|
||||
|
||||
Обращения к памяти обладают временной и пространственной локальностью:
|
||||
|
||||
**Временная локальность** — это понятие, отражающее закономерность обращений программ к памяти и, с высокой вероятностью, проявляющееся в повторном использовании данных, к которым недавно уже обращались.
|
||||
|
||||
**Пространственная локальность** — это понятие, отражающее закономерность обращений программ к памяти и, с высокой вероятностью, проявляющееся в использовании в ближайшем будущем данных, находящихся по соседним адресам.
|
||||
|
||||
Именно из-за этих понятий 90% времени работы программы связано с доступом к 10% адресного пространства этой программы. Если 10% адресного пространства поместить на быстродействующую память (Например кэш-паять), то 90% времени процессор будет работать с памятью на высокой скорости.
|
||||
Поэтому и существует иерархия памяти, которая помогает обходить проблему с быстротой, ёмкостью и дешевизной отдельных уровней памяти. Т.е. если взять быструю, маленькую и дешёвую кэш-память и медленную, большую и дешёвую оперативную память, то получится иерархия памяти, обладающая быстротой, ёмкостью и дешевизной. Это и есть главная причина возникновения иерархии.
|
||||
|
||||
## Статическая и динамическая память
|
||||
|
||||
**Статическая память** (SRAM) — это память, сделанная из транзисторов (см. рис. 3). Адрес ячейки подаётся на `address decoder`, с помощью которого определяется с какой ячейки считывать/записывать данные. На `drivers` подаются данные, которые будут использованы для записи. На выходе стоят усилители сигнала — `Sense amplifiers`. Обычно из статической памяти делается кэш-память.
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Статическая память.*
|
||||
|
||||
Рассмотрим теперь отдельную ячейку памяти (см. рис. 4). Ячейка статической памяти состоит из двух инверторов, которые в свою очередь состоят из двух транзисторов (Например `М1` и `М2`). Эти два инвертора подключены так, что выход первого соединён со входом второго, а выход второго со входом первого. Таким образом, они образуют бистабильную ячейку. Также существуют транзисторы `M5` и `M6`, которые являются ключами, позволяющие положить в эту ячейку либо 0, либо 1. Итого для организации одной статической ячейки памяти требуется 6 транзисторов.
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Ячейка статической памяти.*
|
||||
|
||||
**Динамическая память** (DRAM) — это память, состоящая из конденсаторов (см. рис. 5). Обычно из статической памяти делается оперативная память.
|
||||
|
||||
Ячейка динамической памяти (красный прямоугольник) состоит из одного конденсатора и одного транзистора, являющегося ключом. Если конденсатор заряжен, то в ячейке хранится 1, если разряжен — 0.
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Динамическая память.*
|
||||
|
||||
### Регенерация DRAM
|
||||
|
||||
Ввиду малых размеров конденсатора (а значит и его ёмкости), записанная на нем информация хранится крайне недолго — буквально сотые, а то тысячные доли секунды. Причина тому — саморазряд конденсатора. Для борьбы с "забывчивостью" памяти прибегают к ее **регенерации** — периодическому считыванию ячеек с последующей перезаписью. Во время регенерации все процессы, связанные с работой с памятью, останавливаются.
|
||||
|
||||
### Сравнение SRAM и DRAM
|
||||
|
||||
| Критерий | SRAM | DRAM |
|
||||
|:------------------------------------------|:-----------------------------------------------|:------------------------------------------------|
|
||||
| Доступ к ячейки памяти | В любой момент времени | Недоступна во время регенерации |
|
||||
| Кол-во элементов для одной ячейки памяти | 6-8 элементов | 2 элемента |
|
||||
| Стоимость кб памяти | Высокая стоимость | Низкая стоимость |
|
||||
| Стабильность | Произвольное содержимое памяти после включения | Сохранение данных даже после выключения питания |
|
||||
| Скорость работы | 10-50 нс. | До 100 нс. |
|
||||
| Применение | Кэш-память | Оперативная память |
|
||||
|
||||
## Структура микросхемы памяти
|
||||
|
||||
Рассмотрим структуру устройства микросхемы памяти (см. рис. 6). На вход подаётся адрес ячейки A<sub>m</sub>...A<sub>0</sub>. С помощью `дешифратора адреса столбца` и `дешифратора адреса строки` выделяется нужная ячейка памяти. С помощью `усилителя считывания` на выход подаётся информация с нужной ячейки памяти, которая в дальнейшем идёт на процессор. Также в схеме присутствует устройство `синхронизации и управления`, которое отвечает за корректную работу всех элементов схемы.
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Структура микросхемы памяти.*
|
||||
|
||||
## Блочная память
|
||||
|
||||
Иногда не удаётся сделать память единым блоком, и для увеличения адресного пространства применяется **блочную память** (см. рис. 7). В данной схеме банк памяти может хранить только семибитные адреса, а для получения девятибитного адресного пространства надо объединить четыре таких банка. Для управления ними используется `дешифратор номера банка`, которому на вход подаётся два старших бита адреса, а остальные младшие 7 бит идут сразу на вса банки. В результате на `шину данных` придёт информация из нужной ячейки.
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Блочная память.*
|
||||
|
||||
### Расслоение памяти
|
||||
|
||||
У схемы блочной памяти, рассмотренной в прошлом примере, есть недостаток: если обращения идут к соседним ячейкам памяти, что происходит довольно часто из-за [пространственной локальности](#локальность-по-обращению), то обработка этих обращений будет осуществляться тоже последовательно. Эта проблема решается использованием **расслоения памяти** (см. рис. 8), т.е. соседние адреса будут находиться в разных банках памяти, вследствие чего запросы к соседним ячейкам памяти будут обрабатываться параллельно.
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Расслоение память.*
|
||||
|
||||
## Способы доставки данных
|
||||
|
||||
- Последовательный режим (flow through mode)
|
||||
- Регистровый (register to latch)
|
||||
- Быстрый постраничный (fast page mode)
|
||||
- Пакетный (burst mode)
|
||||
- Конвейерный (pipelined mode)
|
||||
- Метод удвоенной скорости (double data rate)
|
||||
|
||||
Стоит отметить, что все современные компьютеры используют метод удвоенной скорости.
|
||||
|
||||
## Энергонезависимая память
|
||||
|
||||
- Энергонезависимая память сохраняет свое состояние даже при отключении питания
|
||||
- _ROM_: программируется на этапе производства
|
||||
- Программируемая ROM (_PROM_): может быть запрограммирована пользователем один раз
|
||||
- Стираемая PROM (_EPROM_): может быть стерта (УФ, рентген)
|
||||
- Электрически стираемая PROM (_EEPROM_): стирание происходит через подачу электрического сигнала
|
||||
- _Flash-память_: EEPROM с частичной возможностью стирания (по секторам)
|
||||
- Сфера применения энергонезависимой памяти
|
||||
- Встраиваемые программы размещаются в ROM (BIOS, контроллеры дисков, сетевых и графических адаптеров, аппаратно-криптографические средства,…)
|
||||
- Твердотельные накопители (SSD)
|
||||
- Кеш в обычных дисковых накопителях
|
||||
|
||||
### Flash-память
|
||||
|
||||
Рассмотрим устройство ячейки flash-памяти (см. рис. 9). Она очень похожа на транзистор, за исключением наличия `плавающего затвора`, который находится внутри изолятора. Если подать большое напряжение на вход, то некоторые электроны "перепрыгнут" на плавающий затвор. Чем больше напряжение подаём, тем больше электронов будет перепрыгивать на этот затвор. С помощью этого можно задать, несколько уровней заряженности плавающего затвора, тем самым уже можно закодировать несколько бит информации (Например для 2 битов информации потребуется 4 уровня заряженности). Есть один минус у этого: чем больше уровней, тем ниже надёжность этой памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 9. Flash-память.*
|
||||
|
||||
## Защита памяти
|
||||
|
||||
Некоторые системы требуют дополнительную надёжность для памяти (Например система бортового управления самолёта). Рассмотрим схему памяти с повышенной надёжностью (см. рис. 10). На вход подаётся какая-то информация. Она кладётся в память по каналу `M`, однако эта же информация кодируется с помощью блока `F` и также кладётся в память. Когда не кодированная информация возвращается из памяти, её кодируют и сравнивают с уже сохранённой кодированной: если совпадают, то информация подаётся на выход, если нет, то выдаётся сигнал об ошибке.
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Память с повышенной надёжностью.*
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://youtu.be/PBZITnGVdxI?si=EsTtU_rA7ouSCfgP) на видеозапись лекции
|
321
Lectures/16. Cache memory.md
Normal file
321
Lectures/16. Cache memory.md
Normal file
@@ -0,0 +1,321 @@
|
||||
# Лекция 16. Кэш-память
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 16. Кэш-память](#лекция-16-кэш-память)
|
||||
- [Содержание](#содержание)
|
||||
- [Кэш-память](#кэш-память)
|
||||
- [Иерархия памяти](#иерархия-памяти)
|
||||
- [Локальность данных](#локальность-данных)
|
||||
- [Характеристики кэш-памяти](#характеристики-кэш-памяти)
|
||||
- [Существует 3 вида кэш-памяти](#существует-3-вида-кэш-памяти)
|
||||
- [Анализ производительности](#анализ-производительности)
|
||||
- [Кэш прямого отображения](#кэш-прямого-отображения)
|
||||
- [Идентификация строки](#идентификация-строки)
|
||||
- [Множественно-ассоциативный кэш](#множественно-ассоциативный-кэш)
|
||||
- [Полностью ассоциативный кэш](#полностью-ассоциативный-кэш)
|
||||
- [Длина строки (блока)](#длина-строки-блока)
|
||||
- [Алгоритмы замещения данных](#алгоритмы-замещения-данных)
|
||||
- [Стратегии чтения и записи в кэш](#стратегии-чтения-и-записи-в-кэш)
|
||||
- [Основные оптимизации кэш-памяти](#основные-оптимизации-кэш-памяти)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
- [Дополнительные материалы к лекции для саморазвития](#дополнительные-материалы-к-лекции-для-саморазвития)
|
||||
|
||||
## Кэш-память
|
||||
|
||||
С 80-х годов процессоры начали превосходить по производительности память *(рис. 1)*. Этот разрыв в скоростях привёл к потребности в быстром буфере памяти, который мог бы уменьшить задержку при обращении к данным. В 60-70-х годах начались эксперименты и исследования в области быстрых буферов, что привело к созданию **кэш-памяти**.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Изменение в производительности процессоров и памяти с 80-х годов.*
|
||||
|
||||
**Что такое кэш-память?**
|
||||
**Кэш-память** — это небольшой сегмент высокоскоростной памяти, обычно на базе **SRAM** ([**Static Random-Access Memory**](../15.%20Memory.md), расположенный непосредственно на процессоре или рядом с ним. Её главная функция — временное хранение тех данных, к которым процессор часто обращается. Основная цель такой памяти — уменьшить задержку доступа к данным, служа мостом между процессором и основной оперативной памятью.
|
||||
|
||||
**Для чего нужна кэш-память?**
|
||||
Основное **предназначение кэш-памяти** — ускорение доступа процессора к часто используемым данным и командам, минимизируя зависимость от более медленной основной памяти. Благодаря этому, время реакции системы сокращается, делая её более отзывчивой и эффективной.
|
||||
|
||||
## Иерархия памяти
|
||||
|
||||
**Иерархия памяти** - это объединение разных типов памяти с целью получения большой, дешевой, и быстрой памяти, с чем можно более подробно ознакомиться на *(рис. 2)*. Наивысший уровень иерархии (**Cache**) обычно является наиболее быстрым и наименее емким, в то время как нижний уровень обычно имеет наибольший объем, но и наибольшую задержку (**Secondary (external) Memory**).
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Схема расположения разных типов памяти и пирамида иерархии памяти.*
|
||||
|
||||
**SRAM** (Static Random-Access Memory) - тип быстрой полупроводниковой памяти, который сохраняет данные без необходимости периодического обновления. Используется в кэш-памяти процессоров из-за своей высокой скорости.
|
||||
**DRAM** (Dynamic Random-Access Memory) - тип полупроводниковой памяти, который требует периодического обновления для сохранения данных.
|
||||
**SSD** (Solid-State Drive) - устройство хранения данных, работающее на основе NAND-памяти.
|
||||
**HDD** (Hard Disk Drive) - устройство хранения данных, использует магнитные диски для записи и чтения данных, имеет больший объем по сравнению с SSD, но скорость доступа к данным обычно ниже.
|
||||
|
||||
Несмотря на то, что кэш-память во много раз быстрее основной памяти, она еще в большее число раз меньше её. Разумеется объем кэша меняется от процессора к процессору, но для определенности возьмем следующий пример: допустим, в процессорной системе кэш 32МБ, а объем оперативной памяти — 32ГБ. Получается, кэш меньше основной памяти в 1024 раза. Как же так получается, что обращаясь в кэш, процессор умудряется получать именно те данные, которые запрашивал? Ведь если вероятность того, что кэш содержит нужные процессору данные составляет 1/1024-ую, то он будет ухудшать производительность системы, а не улучшать ее. Этому способствует такое явление как **локальность данных**.
|
||||
|
||||
## Локальность данных
|
||||
|
||||
[Локальность данных](https://en.wikipedia.org/wiki/Locality_of_reference) — это набор наблюдений (закономерностей), благодаря которым процессорная система становится чуть более предсказуемой. Эта предсказуемость позволяет использовать кэш эффективно.
|
||||
|
||||
Существует несколько видов локальности, но в данный момент необходимо выделить два ключевых:
|
||||
|
||||
- **временнáя локальность**: если произошло обращение к данной ячейке памяти, высока вероятность того, что в скором времени обратятся к этой же ячейке памяти;
|
||||
- **пространственная локальность**: если произошло обращение к данной ячейке памяти, высока вероятность того, что в скором времени обратятся к соседним ячейкам памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Примеры пространственной и временно́й локальности для разных типов памяти.*
|
||||
|
||||
**Перед созданием Кэш-памяти нам нужно задаться 4-мя вопросами**:
|
||||
|
||||
- Где могут быть размещены данные в кэш-памяти? ([**Размещение строки в разных видах кэшах-памяти**](#существует-3-вида-кэш-памяти))
|
||||
- Как найти данные в кэш-памяти? ([**Идентификация строки**](#идентификация-строки))
|
||||
- Какие данные нужно заместить, при заполненной кэш-памяти? ([**Алгоритмы замещение строки**](#алгоритмы-замещения-данных))
|
||||
- Что происходит при записи в кэш-память? ([**Стратегия записи**](#стратегии-чтения-и-записи-в-кэш))
|
||||
|
||||
## Характеристики кэш-памяти
|
||||
|
||||
- Ёмкость – ***C*** (capacity)
|
||||
- Число наборов – ***S*** (set)
|
||||
*Любая Кэш-память обладает числом наборов. Каждая ячейка основной памяти может претендовать только на свой набор.*
|
||||
- Длина строки (блока) – ***b*** (block)
|
||||
*Порция перемещения данных между разными уровнями иерархии памяти.*
|
||||
- Количество строк (блоков) – ***B*** = C/b
|
||||
- Степень ассоциативности – ***N***
|
||||
*Количество места в кэш-памяти на которое претендует конкретная строка. Каждая ячейка может располагаться только в одном наборе, один набор может состоять из нескольких строк - это и есть степень ассоциативности.*
|
||||
|
||||
**Наборы в кэш-памяти**:
|
||||
Кэш дробится на подгруппы, которые называются наборами. Особенность наборов заключается в том, за каждой ячейкой памяти закреплен свой набор. Иными словами, ячейка памяти может быть загружена не в любое место кэша.
|
||||
|
||||
- Кэш ***состоит из S наборов***, каждый из которых содержит одну или несколько строк.
|
||||
- Взаимосвязь между адресом в памяти и расположением в кэш называется ***отображением***.
|
||||
- Каждый адрес в памяти отображается в ***один и тот же набор кэша***.
|
||||
|
||||
### Существует 3 вида кэш-памяти
|
||||
|
||||
- [Кэш прямого отображения](#кэш-прямого-отображения) – Набор S содержит только одну строку – ***S = B***
|
||||
- [Множественно-ассоциативный кэш](#множественно-ассоциативный-кэш) – Каждый набор S состоит из N строк – ***S = B/N***
|
||||
- [Полностью ассоциативный кэш](#полностью-ассоциативный-кэш) – Имеет только один набор ***S = 1***
|
||||
|
||||
#### Анализ производительности
|
||||
|
||||
- Доля попаданий (hit rate - **HR**)
|
||||
- Доля промахов (miss rate - **MR**)
|
||||
- MR = <span><sup>Число промахов</sup>⁄<sub>Общее число доступов к памяти</sub></span> = 1 - HR
|
||||
- HR = <span><sup>Число попаданий</sup>⁄<sub>Общее число доступов к памяти</sub></span> = 1 - MR
|
||||
- **AMAT** - average memory access time
|
||||
- AMAT = t<sub>cache</sub> + MR<sub>cache</sub> *(t<sub>MM</sub> + MR<sub>MM</sub>* t<sub>VM</sub>)
|
||||
|
||||
Пример:
|
||||
|
||||
| Уровень памяти | Время доступа в тактах | Процент промахов |
|
||||
|:-------------------|:----------------------:|:----------------:|
|
||||
| Кэш-память | 1 | 10% |
|
||||
| Оперативная память | 100 | 0% |
|
||||
|
||||
*AMAT* = 1 + 0.1 *(100) = 11
|
||||
Какой должен быть MR, чтобы снизить AMAT до 1.5 тактов?
|
||||
1 + m* (100) = 1.5 -> m = 0.005%
|
||||
|
||||
## Кэш прямого отображения
|
||||
|
||||
Рассмотрим *(рис. 4)*. Здесь представлена основная память, имеющая 32-х битный адрес. В этом примере кэш будет состоять из 8 наборов при длине строки, равной одному слову.
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Структура кэша, состоящего из 8 наборов, где длина строки равна одному слову.*
|
||||
|
||||
### Идентификация строки
|
||||
|
||||
Каждая ячейка памяти претендует только на свой набор и имеет свой уникальный адрес. На *(рис. 5)* подробнее рассмотрим как уникальный адрес делится на несколько частей:
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Схематичное представление разделения уникального адреса ячейки памяти на составляющие части.*
|
||||
|
||||
где
|
||||
Первые 2 бита (**Byte Offset**) - смещение внутри слова
|
||||
Следующие три бита (**Set**) указывают, на какой набор претендует ячейка памяти.
|
||||
Оставшиеся 10 бит представляют собой **Tag**, с помощью которого определяется, находится ли ячейка в кэш-памяти или нет.
|
||||
|
||||
**Пример:**
|
||||
|
||||
```assembly
|
||||
addi $t0, $0, 5 # Инициализируем счетчик в регистре $t0 значением 5
|
||||
loop: beq $t0, $0, done # Загружаем значения из памяти по адресам 0x4, 0xC и 0x8 в регистры $t1, $t2 и $t3 соответственно.
|
||||
lw $t1, 0x4($0)
|
||||
lw $t2, 0xC($0)
|
||||
lw $t3, 0x8($0)
|
||||
addi $t0, $t0, -1 # Уменьшаем счетчик на 1.
|
||||
j loop # Повторяем цикл, пока счетчик в регистре $t0 не достигнет нуля.
|
||||
done:
|
||||
```
|
||||
|
||||
Давайте разберём, как это работает *(рис. 6)*:
|
||||
У нас есть цикл с 5 итерациями, что означает 15 обращений к памяти. При первом проходе по циклу мы сталкиваемся с промахами и записываем их в ячейки памяти. На последующих итерациях цикла у нас уже будут попадания.
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Визуализация процесса выполнения ассемблерного кода, представленного выше.*
|
||||
|
||||
В итоге из 15 обращений к памяти у нас 3 промаха. Теперь можем рассчитать **MR**:
|
||||
|
||||

|
||||
|
||||
**Пример вытеснения (evict):**
|
||||
|
||||
```assembly
|
||||
addi $t0, $0, 5 # Инициализируем счетчик в регистре $t0 значением 5
|
||||
loop: beq $t0, $0, done
|
||||
lw $t1, 0x4($0) # Загружаем значения из памяти по адресу 0x4 в регистр $t1
|
||||
lw $t2, 0x24($0) # Загружаем значения из памяти по адресу 0x24 в регистр $t2
|
||||
addi $t0, $t0, -1 # Уменьшаем счетчик на 1.
|
||||
j loop # Повторяем цикл, пока счетчик в регистре $t0 не достигнет нуля.
|
||||
done:
|
||||
```
|
||||
|
||||
Загрузка двух ячеек памяти — 4 и 24 — приводит нас к проблеме *(рис. 7)*. Обе эти ячейки ссылаются на один и тот же набор. Из-за этого при каждом обращении к памяти мы будем получать промах.
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Визуализация процесса выполнения ассемблерного кода, иллюстрирующая проблему вытеснения ячейки памяти с адресами 4 и 24.*
|
||||
|
||||
Соответственно **MR** в данном случае будет 100%:
|
||||
|
||||

|
||||
|
||||
## Множественно-ассоциативный кэш
|
||||
|
||||
Идея множественно-ассоциативного кэша заключается в наличии нескольких строк внутри одного набора. Увеличив ассоциативность, мы теперь имеем двухсекционный кэш (**Way 1** и **Way 0**) *(рис. 8)*. Каждая ячейка памяти может претендовать на любую из этих двух секций, и, в таком случае, вытеснения не произойдет.
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Структура множественно-ассоциативного кэша. Отображены две ассоциативные секции — Way 1 и Way 0 — внутри одного набора.*
|
||||
|
||||
Но такой кэш *(рис. 9)* сразу будет работать медленнее из-за появившегося мультиплексора на выходе, более сложен в реализации, увеличивается сложность вычислений.
|
||||
**Тот же пример:**
|
||||
|
||||

|
||||
|
||||
*Рис. 9. При обращении к адресам 0x4 и 0x24 видно, что ячейки памяти могут быть распределены по разным секциям (Way 1 и Way 0), что предотвращает вытеснение.*
|
||||
|
||||
Теперь у нас будет два промаха в первом цикле, а уже на следующих, мы без проблем сможем обращаться к обеим ячейкам, таким образом теперь MR = 20%
|
||||
|
||||
## Полностью ассоциативный кэш
|
||||
|
||||
В полностью ассоциативном кэше *(рис. 10)* мы оставляем **только один набор**, то есть любая ячейка из памяти, может попасть в любую секцию, в таком варианте кэша отлично решается проблема вытеснения, но этим самым реализация становится крайне объемной и медленной, поэтому он находит применение в более специфических местах.
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Существует только один набор, но с множеством секций, позволяя любой ячейке из памяти быть загруженной в любую доступную секцию кэша.*
|
||||
|
||||
### Длина строки (блока)
|
||||
|
||||
Если процессор не находит в кэше данные той ячейки памяти, к которой он обращался, он забирает эти данные из основной памяти, одновременно перемещая их в кэш. Как вы знаете, благодаря **пространственной локальности** высока вероятность того, что вскоре процессор обратится и к соседним ячейкам памяти. Поэтому эффективно будет переместить в кэш данные не только этой ячейки памяти, но и данные ячеек памяти, лежащих рядом с ней, образуя **блок данных**. Таким образом, кэш оперирует данными не на уровне ячеек памяти (**слов**), а на уровне блоков ячеек (**строк**). В простейшем случае, в одной строке находится одно слово, т.е. кэш загружает только ту ячейку памяти, к которой он обращался.
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Схематическое представление деления адреса в контексте длины строки (или блока) кэша.*
|
||||
|
||||
Здесь *(рис. 11)* у нас есть адрес делится на чуть большее количество секций, байтовое смещение (**Bite Offsets**) для байта внутри одного слова, смещение блока (**Block Offsets**) т.е. смещение внутри строки, бит для выбора набора (**Set**) и 27 бит под **Tag**.
|
||||
|
||||
**Плюсы**:
|
||||
При обращении к одной инструкции из кэша автоматически загружаются и следующие три инструкции, что обеспечивает быстрый доступ к большому объему данных.
|
||||
**Минусы**: Пропускная способность канала между процессором и памятью. Промах с длинной строкой будет стоить дороже, чем промах с одним словом.
|
||||
|
||||
**Вернемся к первому примеру:**
|
||||
|
||||
```assembly
|
||||
addi $t0, $0, 5
|
||||
loop: beq $t0, $0, done
|
||||
lw $t1, 0x4($0)
|
||||
lw $t2, 0x24($0)
|
||||
addi $t0, $t0, -1
|
||||
j loop
|
||||
done:
|
||||
```
|
||||
|
||||
Благодаря размещению всей строки в памяти, у нас будет только один промах, а все последующие обращения приведут к попаданиям.
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Схема демонстрирует эффективность использования строк в кэше, минимизируя количество промахов при последовательных обращениях.*
|
||||
|
||||
И теперь мы получим более низкий MR:
|
||||
|
||||

|
||||
|
||||
## Алгоритмы замещения данных
|
||||
|
||||
- **LRU** (Least Recently Used) – наиболее давнего использования +
|
||||
*Рассмотрим на примере двухсекционного кэша *(рис. 13)*, где у нас добавляется дополнительный бит (**U** - used) куда помещается номер секции, которая сейчас не использовалась. Т.е. если сейчас мы записываем в секцию 0 то в этот бит попадает 1, и если потребуется какую то из ячеек убрать, то устройство управления этим кэшем, выберет ту ячейку, которая указана в поле U.*
|
||||
|
||||

|
||||
|
||||
*Рис. 13. Схема работы алгоритма замещения данных LRU на примере двухсекционного кэша.*
|
||||
|
||||
- **PLRU** (Pseudo-Least Recently Used) – псевдо наиболее давнего использования +/–
|
||||
*Все секции делятся пополам, которые устроены по алгоритму LRU, а внутри конкретная ячейка выбирается случайным образом.*
|
||||
- **FIFO** (First In First Out) – замещение в порядке очереди
|
||||
*Данные выходят в том же порядке, в котором заходили.*
|
||||
- **LFU** (Least Frequently Used) – наименее частого использования +
|
||||
*С каждой секцией ассоциирован счетчик, и при каждом обращении к секции, счетчик у конкретной ячейки увеличивается. Замещается ячейка с наименьшим числом счетчика.*
|
||||
- **RND** (Random Replacement) – замена случайной строки –
|
||||
- **CLOCK** – циклический список с указателем +
|
||||
*С каждой ячейкой ассоциирован бит, когда к ячейка обращаются, этот бит устанавливается в 1, а при необходимости замещения алгоритм начинает просматривать, что закреплено за конкретной секцией, если 1, то она меняется на 0 и так далее, пока снова не наткнется 0, тогда замещает эту ячейку.*
|
||||
|
||||
Количество промахов на 1000 обращений к памяти:
|
||||
|
||||

|
||||
|
||||
*Рис. 14. Табличка сравнения алгоритмов замещения данных в контексте различных размеров кэш-памяти и секций. Как видно из данных, при увеличении объема кэш-памяти разница в количестве промахов между различными алгоритмами уменьшается.*
|
||||
|
||||
### Стратегии чтения и записи в кэш
|
||||
|
||||
- Стратегии чтения
|
||||
- Чтение с параллельной выборкой (look-aside)
|
||||
- Чтение со сквозным просмотром (look-through)
|
||||
- Стратегии записи
|
||||
- Сквозная запись (write-through) - пишем сразу и в кэш и в память
|
||||
- Сквозная запись с отображением
|
||||
- Сквозная запись без отображения
|
||||
- Буферизированная сквозная запись - пишем сразу и в кэш и в память, но через буфер
|
||||
- Отложенная запись (write-back) - пишем только при вытеснении из кэша
|
||||
- В среднем на 10% эффективнее сквозной записи. Чаще используется
|
||||
|
||||
**Многоуровневый кэш.**
|
||||
Для чего нужны уровни кэша *(рис. 15)*? Давайте проверим если ли прирост производительности с помощью AMAT.
|
||||
|
||||

|
||||
|
||||
*Рис. 15. Пирамида иерархии памяти.*
|
||||
|
||||
Допустим:
|
||||
t<sub>L1</sub> = 1
|
||||
t<sub>L2</sub> = 10
|
||||
t<sub>MM</sub> = 100
|
||||
MR<sub>L1</sub> = 5%
|
||||
MR<sub>L2</sub> = 20%
|
||||
*AMAT* = t<sub>L1</sub> + MR<sub>L1</sub> *(t<sub>L2</sub> + MR<sub>L2</sub>* t<sub>MM</sub>) = 1 + 0.05 *(10 + 0.2* 100) = 2.5 такта
|
||||
|
||||
А теперь уберем кэш второго уровня:
|
||||
*AMAT<sub>without L2</sub>* = 1 + 0.05 * (100) = 6 тактов
|
||||
Т.е. многоуровневый кэш повышает производительность, но требует больших аппаратных затрат.
|
||||
|
||||
Многоуровневый кэш может быть построен по одному из двух принципов:
|
||||
|
||||
- Инклюзивный кэш.
|
||||
*В более низких уровнях памяти, содержится копия тех что выше.*
|
||||
- Эксклюзивный кэш.
|
||||
*На более низких уровнях памяти нет копии верхнего уровня.*
|
||||
|
||||
## Основные оптимизации кэш-памяти
|
||||
|
||||
- Больший размер блока для уменьшения доли промахов.
|
||||
- Кэши большего объема для уменьшения доли промахов.
|
||||
- Увеличение ассоциативности для уменьшения доли промахов.
|
||||
- Многоуровневые кэши для уменьшения потерь на промахах.
|
||||
- Предоставление приоритета промахам считывания по отношению к записям для уменьшения потерь на промахи.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://youtu.be/1PWTr6RogZQ?list=PL0def37HEo5KHPjwK7A5bd4RJGg4djPVf) на видеозапись лекции
|
||||
|
||||
## Дополнительные материалы к лекции для саморазвития
|
360
Lectures/17. Virtual memory. Operating systems.md
Normal file
360
Lectures/17. Virtual memory. Operating systems.md
Normal file
@@ -0,0 +1,360 @@
|
||||
# Лекция 17. Виртуальная память. Операционные системы
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 17. Виртуальная память. Операционные системы](#лекция-17-виртуальная-память-операционные-системы)
|
||||
- [Содержание](#содержание)
|
||||
- [Виртуальная память](#виртуальная-память)
|
||||
- [Виды адресов](#виды-адресов)
|
||||
- [Преобразование адреса](#преобразование-адреса)
|
||||
- [Реализация виртуальной памяти в процессоре](#реализация-виртуальной-памяти-в-процессоре)
|
||||
- [Физические и виртуальные страницы](#физические-и-виртуальные-страницы)
|
||||
- [Сравнение кэш и виртуальной памяти](#сравнение-кэш-и-виртуальной-памяти)
|
||||
- [Особенности виртуальной памяти](#особенности-виртуальной-памяти)
|
||||
- [Защита и приватность](#защита-и-приватность)
|
||||
- [Основная память используется как кэш для внешней памяти](#основная-память-используется-как-кэш-для-внешней-памяти)
|
||||
- [Буфер ассоциативной трансляции (TLB)](#буфер-ассоциативной-трансляции-tlb)
|
||||
- [Использование TLB](#использование-tlb)
|
||||
- [Метод ключей защиты](#метод-ключей-защиты)
|
||||
- [Использование кэш и виртуальной памяти](#использование-кэш-и-виртуальной-памяти)
|
||||
- [Стратегии замещения страниц](#стратегии-замещения-страниц)
|
||||
- [Стратегия обратной записи (write-back)](#стратегия-обратной-записи-write-back)
|
||||
- [Стратегия вытеснения редко используемых страниц (LRU)](#стратегия-вытеснения-редко-используемых-страниц-lru)
|
||||
- [Многоуровневые таблицы страниц](#многоуровневые-таблицы-страниц)
|
||||
- [Метод граничных регистров](#метод-граничных-регистров)
|
||||
- [Операционная система](#операционная-система)
|
||||
- [Процесс vs. программа](#процесс-vs-программа)
|
||||
- [Цели операционной системы](#цели-операционной-системы)
|
||||
- [Управление процессами и ресурсами в ядре операционной системы](#управление-процессами-и-ресурсами-в-ядре-операционной-системы)
|
||||
- [Виртуальные машины](#виртуальные-машины)
|
||||
- [Прерывания и исключения](#прерывания-и-исключения)
|
||||
- [Системные вызовы](#системные-вызовы)
|
||||
- [Системные вызовы RISC-V](#системные-вызовы-risc-v)
|
||||
- [Жизненный цикл процесса](#жизненный-цикл-процесса)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
|
||||
## Виртуальная память
|
||||
|
||||
**Виртуальная память** – это способ автоматического управления иерархической памятью, при котором для нескольких ее уровней организуется единое адресное пространство. Благодаря этому можно создать для программиста видимость памяти большого объема. При этом, при перемещении данных между уровнями для большинства обращений к памяти обеспечивается скорость доступа, равная скорости более быстрых типов памяти (благодаря такому свойству как **локальность по обращению**).
|
||||
|
||||
Когда основная (оперативная) память переполняется, операционная система переносит часть данных во вторичную память (hdd/sdd), освобождая основную память для других задач.
|
||||
|
||||
Виртуальная память разделяет "виртуальные" адреса, используемые приложениями, и "физические" адреса, по которым хранятся данные в реальности *(рис. 1)*. Соответствие между виртуальными и физическими адресами хранится в памяти: когда процессор запрашивает виртуальный адрес, ему предоставляется соответствующий физический адрес. Ячейка памяти может физически располагаться либо во внешней памяти (**Secondary Memory**), либо в оперативной (**Physical Memory**). Во время взаимодействия пользователя с приложением, оно подгружается в оперативную память, а неактивные части выгружаются во внешнюю память.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Схема работы виртуальной памяти, показывающая отображение виртуальных адресов на физические и перенос данных между оперативной и внешней памятью.*
|
||||
|
||||
### Виды адресов
|
||||
|
||||
Существует два вида адресов:
|
||||
|
||||
- **Виртуальный адрес**
|
||||
- Адрес генерируется процессом
|
||||
- Специфичное приватное адресное пространство процесса
|
||||
*Представляет собой адрес в виртуальной памяти, который используется программами и операционной системой для идентификации данных или инструкций в памяти. Кроме того, виртуальные адреса предоставляют изоляцию между процессами. Благодаря тому, что каждый процесс работает в своем виртуальном адресном пространстве, один процесс не может случайно или намеренно повредить память другого процесса.*
|
||||
- **Физический адрес**
|
||||
- Адрес используется для доступа к физической памяти
|
||||
- Операционная система определяет отображение виртуальных адресов на физические
|
||||
*Реальный адрес в оперативной памяти системы. Когда данные или инструкция должны быть
|
||||
получены или сохранены, процессор обращается к физическому адресу.*
|
||||
|
||||
### Преобразование адреса
|
||||
|
||||
В основе процесса преобразования адреса *(рис. 2)* лежит структура данных, известная как таблица страниц. Она содержит информацию о том, как виртуальные страницы (блоки виртуальной памяти) соотносятся с физическими блоками в оперативной памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Схема работы таблицы страниц, отображающая виртуальные страницы на физические блоки оперативной памяти.*
|
||||
|
||||
## Реализация виртуальной памяти в процессоре
|
||||
|
||||
На *(рис. 3)* представлен пример процессора с модифицированной гарвардской архитектурой без виртуальной памяти
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Процессор на базе модифицированной гарвардской архитектуры без использования виртуальной памяти.*
|
||||
|
||||
На *(рис. 4)* представлен пример архитектуры того же процессора, но с использованием виртуальной памяти, в котором добавляется дополнительный блок **MMU (Memory Management Unit)** - устройство управление памятью, он преобразует **ФА** (Физические адреса) в **ВА** (Виртуальные Адреса)
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Архитектура процессора с виртуальной памятью и блоком MMU для преобразования ФА в ВА.*
|
||||
|
||||
Рассмотрим более детально работу MMU на *(рис. 5)*. Как мы можем увидеть, процессор с виртуальной памятью не обязан работать исключительно через виртуальную память. Это позволяет обеспечивать гибкость в обращении с ресурсами и оптимизировать производительность в зависимости от потребностей задачи.
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Блок-схема MMU.*
|
||||
|
||||
## Физические и виртуальные страницы
|
||||
|
||||
При работе с виртуальной памятью данные могут быть организованы двумя способами:
|
||||
|
||||
- **Страничная организация памяти**: Данные разбиваются на блоки одинакового размера, называемые страницами. В каждой странице смещение данных идентично, что соответствует смещению внутри виртуального адреса. Это можно сравнить с работой кэш-памяти.
|
||||
- **Сегментная организация памяти**: Данные разделяются на сегменты разного размера, в зависимости от их характера и назначения.
|
||||
|
||||
Рассмотрим компьютерную систему с 128 МБ физической памяти и поддержкой виртуальной памяти размером 2 ГБ. На (рис. 6) представлена страничная таблица. В этой системе вся память поделена на равные блоки, обычно размером 4 КБ, которые называются страницами.
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Как адреса из виртуальной памяти, ссылаются на адреса в физической памяти.*
|
||||
|
||||
В памяти системы находится часть страничной таблицы *(рис. 7)*. Каждая ячейка этой таблицы содержит число, указывающее на определенный блок физической памяти. В этой таблице также присутствует бит `V`. Если значение бита `V` равно **1**, это указывает, что страница находится в основной памяти. Если значение равно **0**, страница располагается во внешней памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Страничная таблица.*
|
||||
|
||||
## Сравнение кэш и виртуальной памяти
|
||||
|
||||
Рассмотрим *(рис. 8)*. Слева представлены характеристики и параметры кэширования, включая размеры строк, время доступа и обработку промахов. Справа — аналогичные характеристики для виртуальной памяти, включая размеры страниц и время обработки различных операций.
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Таблица сравнения работы кэш-памяти и виртуальной памяти.*
|
||||
|
||||
## Особенности виртуальной памяти
|
||||
|
||||
### Защита и приватность
|
||||
|
||||
- Каждый процесс использует приватное адресное пространство.
|
||||
>Каждый запущенный процесс (или приложение) в системе получает свое уникальное адресное пространство, изолированное от других процессов. Таким образом, одно приложение не может напрямую обратиться к памяти другого приложения, что обеспечивает безопасность и стабильность системы.
|
||||
|
||||
- Подкачка страниц.
|
||||
> Это механизм, при котором операционная система перемещает данные между физической памятью и пространством подкачки (часто расположенным на жестком диске). Это позволяет ОС освобождать физическую память для активных процессов, отправляя менее активные или неактивные страницы в пространство подкачки.
|
||||
|
||||
### Основная память используется как кэш для внешней памяти
|
||||
|
||||
- Позволяет запускать программы большие, чем основная память.
|
||||
>Благодаря виртуальной памяти можно запускать программы, требующие больше памяти, чем фактически имеется в системе. Это достигается путем использования комбинации физической памяти и пространства подкачки.
|
||||
|
||||
- Скрывает разницу в машинных конфигурациях.
|
||||
>Виртуальная память позволяет программам работать на различных аппаратных конфигурациях, не заботясь о реальном объеме имеющейся памяти или спецификации жесткого диска. Это упрощает разработку и использование программ.
|
||||
|
||||
- Цена виртуализации – это трансляция каждого обращения к памяти.
|
||||
> Эта дополнительная операция добавляет некоторую задержку, что делает доступ к виртуальной памяти медленнее по сравнению с прямым доступом к физической памяти.
|
||||
Однако, существуют специализированные методы и технологии, призванные минимизировать эту задержку и оптимизировать процесс трансляции. Одним из таких методов является использование **Буфера Ассоциативной Трансляции или TLB**.
|
||||
|
||||
## Буфер ассоциативной трансляции (TLB)
|
||||
|
||||
Каждый раз, когда система обращается к памяти, необходимо перевести виртуальный адрес в физический. Этот процесс трансляции адреса может стать затратным, поскольку каждое такое обращение требует дополнительного обращения к страничной таблице, что фактически удваивает количество операций с памятью.
|
||||
|
||||
Чтобы оптимизировать этот процесс, было предложено решение в виде кэширования недавно транслированных страниц в специальной высокоскоростной памяти, называемой Буфером Ассоциативной Трансляции или Translation Lookaside Buffer (TLB).
|
||||
|
||||
Когда система обращается к странице, которая уже находится в TLB (**TLB hit**), трансляция адреса может быть выполнена всего за один системный такт. Но, если страница не находится в TLB (**TLB miss**), системе придется обратиться к страничной таблице для получения нужного адреса и обновления содержимого TLB.
|
||||
|
||||
Другими словами, TLB – это кэш-память с высокой степенью ассоциативности в которой хранятся последние записи страничной таблицы *(рис. 9)*.
|
||||
|
||||

|
||||
|
||||
*Рис. 9. При обращении по виртуальному адресу 0x24C7 данные будут загружены из кэша. В то время как для адреса 0x5FB0 необходимо будет выполнить обращение к основной памяти.*
|
||||
|
||||
### Использование TLB
|
||||
|
||||
Буфер ассоциативной трансляции играет ключевую роль в современной системе управления памятью. Обычный TLB может содержать от 32 до 128 входов с степенью ассоциативности между 4 и 8. Современные процессоры часто используют иерархическую структуру TLB, что может включать в себя комбинацию, например, L1 TLB с 128 входами и L2 TLB с 2K входами.
|
||||
|
||||
Переключение между процессами является дорогостоящей операцией, главным образом из-за необходимости очистки TLB. Тем не менее можно включить ID процесса в TLB для предотвращая потребность в очистке *(рис. 10.)*.
|
||||
|
||||
При промахе TLB, система обращается к страничной таблице в основной памяти. Если требуемая страница присутствует в основной памяти, система выполняет преобразование виртуального номера страницы (VPN) в физический номер страницы (PPN) и обновляет TLB. В противном случае происходит страничный сбой, который всегда обрабатывается программно.
|
||||
|
||||
Для навигации по страничной таблице обычно используется специальное аппаратное устройство, называемое блоком управления памятью (**MMU**). Некоторые популярные архитектуры, такие как `RISC-V` и `x86`, реализуют страничную таблицу на аппаратном уровне.
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Виртуальный адрес разбивается на две части:
|
||||
ASID (ID процесса) – идентифицирует конкретный процесс, к которому относится данный адрес.
|
||||
VPN (номер виртуальной страницы) – указывает на конкретную виртуальную страницу в рамках выбранного процесса.*
|
||||
|
||||
Для обеспечения повышенной безопасности, необходимо реализовать дополнительную проверку по ASID. Этот момент приводит нас к управлению памятью — **Методу ключей защиты**.
|
||||
|
||||
### Метод ключей защиты
|
||||
|
||||
Рассмотрим *(рис. 11)*. Ключ защиты программы представляет собой уникальный ID, который хранится в специальном регистре. Операционная система, работая в привилегированном режиме, имеет возможность управлять данным регистром. При формировании адреса программой, часть этого адреса сравнивается с текущим ключом защиты. Если совпадение найдено, то обращение к памяти разрешено. В противном случае, доступ к памяти блокируется.
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Метод ключей защиты.*
|
||||
|
||||
## Использование кэш и виртуальной памяти
|
||||
|
||||
Для того чтобы использовать кэш память и виртуальную память одновременно есть несколько вариантов *(рис. 12.)*
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Виртуально-адресуемый кэш — сначала кэш, потом TLB. Физически-адресуемый кэш — сначала TLB, потом кэш.*
|
||||
|
||||
**Виртуально-адресуемый кэш (VAC)**
|
||||
Преимущества:
|
||||
|
||||
- **Быстрота**.
|
||||
*Поскольку трансляция адресов не требуется до проверки кэша, доступ к кэшу может быть быстрее.*
|
||||
- **Поддержка разделяемых страниц**.
|
||||
*Если два процесса используют одну и ту же физическую страницу, VAC может эффективно кэшировать её для обоих процессов.*
|
||||
|
||||
Недостатки:
|
||||
|
||||
- **Проблемы с однородностью (aliasing)**.
|
||||
*Поскольку одна и та же физическая страница может быть отображена на несколько виртуальных адресов, это может привести к нежелательным промахам в кэше.*
|
||||
- **При переключении контекста часто требуется сбросить кэш**.
|
||||
|
||||
**Физически-адресуемый кэш**
|
||||
Преимущества:
|
||||
|
||||
- **Отсутствие проблем с однородностью**.
|
||||
*Так как используются физические адреса, вероятность возникновения ситуации, когда два разных виртуальных адреса ссылаются на одну и ту же ячейку кэша, минимальна.*
|
||||
- **Стабильность при переключении контекста**.
|
||||
*Нет необходимости очищать кэш при смене процесса.*
|
||||
|
||||
Недостатки:
|
||||
|
||||
- **Задержка из-за трансляции**.
|
||||
*Прежде чем можно проверить кэш, виртуальный адрес должен быть переведен в физический, что добавляет дополнительное время ожидания.*
|
||||
|
||||
Но на практике чаще используется третий вариант — параллельное обращение к TLB и кэш-памяти *(рис. 13)*
|
||||
|
||||

|
||||
|
||||
*Рис. 13. Схема параллельного обращения процессора к TLB и кэш-памяти.*
|
||||
|
||||
## Стратегии замещения страниц
|
||||
|
||||
Стратегии замещения страниц в виртуальной памяти очень похожи на стратегии замещения в кэш-памяти. Они определяют, какую страницу следует вытеснить из основной памяти при необходимости загрузки новой страницы.
|
||||
|
||||
### Стратегия обратной записи (write-back)
|
||||
|
||||
Эта стратегия предполагает, что изменения записываются только в кэше. Данные в основной памяти обновляются только тогда, когда страница вытесняется из кэша.
|
||||
|
||||
Для поддержания работы с этой стратегией в таблице страниц используется дополнительное поле `D` (dirty bit). Если бит установлен, это указывает, что страница была изменена и требует обновления в основной памяти.
|
||||
|
||||
### Стратегия вытеснения редко используемых страниц (LRU)
|
||||
|
||||
LRU вытесняет страницы, которые не использовались дольше всех. Это обеспечивает предположение, что страницы, которые не использовались в недавнем прошлом, вероятно, не будут использоваться и в ближайшем будущем.
|
||||
|
||||
Для реализации этой стратегии в таблице страниц используется дополнительное поле `U` (use bit). Этот бит показывает, была ли страница использована в недавнем прошлом. Операционная система может периодически сбрасывать этот бит для всех страниц, а затем наблюдать, какие из них используются снова.
|
||||
|
||||
## Многоуровневые таблицы страниц
|
||||
|
||||
Вместо одной огромной таблицы страниц, которая бы отображала каждую возможную страницу виртуальной памяти на страницу физической памяти, многоуровневые таблицы разбивают эту информацию на несколько меньших таблиц *(рис. 14)*, что более рационально для многозадачных операционных систем
|
||||
|
||||
Каждый виртуальный адрес представляется тремя частями:
|
||||
**Page Tales Number** — запись в основной таблице, где мы найдем нашу вторую побочную таблицу.
|
||||
**Page Tales Offset** — указывают на строку во второй таблице.
|
||||
**Page Offset** — смещение, указывает на конкретную ячейку памяти внутри соответствующей таблицы.
|
||||
|
||||

|
||||
|
||||
*Рис. 14. Пример многоуровневой таблицы страниц.*
|
||||
|
||||
Благодаря этому легко реализуется **приватное адресное пространство** *(рис. 15)* между процессами, где:
|
||||
|
||||
- Каждый процесс имеет собственную страничную таблицу
|
||||
- Страничная таблица включает в себя все страницы процесса
|
||||
- Страничные таблицы позволяют хранить страницы процесса не непрерывно
|
||||
|
||||

|
||||
|
||||
*Рис. 15. Приватное адресное пространство.*
|
||||
|
||||
## Метод граничных регистров
|
||||
|
||||
Существует так же другой подход - **сегментная реализация памяти**. В сегментной памяти вся память делится не на одинаковые страницы, а на сегменты разной величины. Для того чтобы операционная система могла регулировать чтобы процесс не выходил за свои сегменты используется подход который называется **метод граничных регистров** *(рис. 16)*.
|
||||
|
||||
При каждом обращении процесса к памяти операционная система проверяет, чтобы адрес был между значениями регистров базы и границы. Если адрес находится за пределами этого диапазона, генерируется ошибка, и процесс не может получить доступ к памяти вне своего выделенного блока.
|
||||
|
||||

|
||||
|
||||
*Рис. 16. Метод граничных регистров.*
|
||||
|
||||
## Операционная система
|
||||
|
||||
Когда на машине одновременно запущены несколько программ, каждая из них не имеет возможности прямого обращения к аппаратным ресурсам. Вместо этого именно операционная система определяет, как эти программы будут разделять доступ к оборудованию. Это осуществляется для обеспечения безопасности и эффективности, так как **только операционная система** имеет неограниченный доступ к аппаратным ресурсам. Когда программа хочет взаимодействовать с этими ресурсами, она обращается к программному интерфейсу, известному как **ABI (Application Binary Interface)**.
|
||||
|
||||
Этот интерфейс служит мостом между операционной системой и запущенной программой, обеспечивая гладкое взаимодействие между ними.
|
||||
|
||||

|
||||
|
||||
*Рис. 17. Схема, демонстрирующая взаимодействие между запущенными программами, операционной системой и аппаратными ресурсами.*
|
||||
|
||||
### Процесс vs. программа
|
||||
|
||||
- Программа – это набор инструкций (только ее код)
|
||||
- **Процесс** – это экземпляр программы, которая выполняется
|
||||
- Состоит из **кода программы** и **контекста** (регистры, содержимое памяти и другие ресурсы)
|
||||
- Ядро операционной системы **(OS Kernel)** это привилегированный процесс
|
||||
|
||||
### Цели операционной системы
|
||||
|
||||
1. **Защита и приватность**: Операционная система обеспечивает строгую изоляцию между процессами, чтобы гарантировать, что один процесс не может вмешиваться в работу другого или получать доступ к его данным. Это обеспечивает безопасность данных и предотвращает возможные ошибки или злонамеренные действия. Процесс может взаимодействовать только со своим выделенным адресным пространством и ресурсами, исключая возможность несанкционированного доступа к данным других процессов.
|
||||
|
||||
2. **Абстракция**: Предоставление удобного и понятного интерфейса для работы с аппаратными ресурсами. Она скрывает сложные детали реализации аппаратного обеспечения, позволяя программам и пользователю взаимодействовать с системой на более высоком, абстрактном уровне. Это облегчает разработку приложений, так как разработчикам не нужно знать о всех нюансах работы аппаратуры.
|
||||
|
||||
3. **Управление ресурсами**: Действует как посредник между аппаратными ресурсами компьютера и запущенными на нем процессами. Она определяет, какие процессы будут выполняться, когда и сколько ресурсов (CPU, память или внешние устройства) они будут использовать. Этот контроль необходим для оптимизации производительности, обеспечения справедливого доступа к ресурсам и предотвращения конфликтов.
|
||||
|
||||
### Управление процессами и ресурсами в ядре операционной системы
|
||||
|
||||
Основная задача ядра операционной системы – это управление ресурсами компьютера и обеспечение стабильного взаимодействия между аппаратной и программной частями. **Каждому процессу** выделяется **приватное адресное пространство** в физической памяти, гарантируя, что процессы не могут вмешиваться в память друг друга. Этим обеспечивается **безопасность и изоляция** при выполнении приложений.
|
||||
|
||||
В области управления процессами, ядро операционной системы **планирует доступ к CPU**. Каждому процессу выделяется определенное **время работы на процессоре**, и приложение не может использовать больше этого времени.
|
||||
|
||||
Помимо управления ресурсами, ядро ОС также предоставляет интерфейс для взаимодействия программ с аппаратной частью. Этот интерфейс, известный как **системные вызовы (system calls)**, позволяет процессам получать доступ к таким службам, как файловая система или сетевое оборудование.
|
||||
|
||||
### Виртуальные машины
|
||||
|
||||
Виртуальные машины представляют собой эффективный инструмент, который позволяет операционной системе создавать изолированные среды для каждого процесса. **Каждый процесс** при этом "думает", что он выполняется на отдельной, независимой машине. На деле, конечно, эта машина не имеет реального аппаратного обеспечения, ведь она является лишь **эмуляцией** реального компьютера *(рис. 18)*.
|
||||
|
||||
Суть виртуальной машины заключается в том, чтобы предоставить программам иллюзию независимости и полного контроля над ресурсами, в то время как реальное аппаратное обеспечение делится между несколькими такими виртуальными средами. Эта концепция оказалась настолько мощной и универсальной, что сегодня она используется не только в рамках операционных систем, но и во многих других областях информационных технологий.
|
||||
|
||||
Процесс, исполняемый на **RISC-V**, интерпретируется через **RISC-V эмулятор**. В то время как **JavaScript** работает внутри **браузера**, который в свою очередь взаимодействует с **ABI OS**. Все это управляется **операционной системой**, которая напрямую работает с **x86 аппаратным обеспечением**.
|
||||
|
||||

|
||||
|
||||
*Рис. 18. Концепция виртуальных машин.*
|
||||
|
||||
### Прерывания и исключения
|
||||
|
||||
**Исключение** – событие которое требует обработки операционной системой (неподдерживаемая инструкция, системный вызов, деление на ноль…) *(рис. 19)*
|
||||
|
||||

|
||||
|
||||
*Рис. 19. Схема работы с исключениями.*
|
||||
|
||||
**Прерывания** – асинхронные события, требующие обработки операционной системой (таймер, мышка, клавиатура…)
|
||||
|
||||
### Системные вызовы
|
||||
|
||||
Эти вызовы обеспечивают возможность программам обращаться к таким базовым функциям, как **доступ к файлам**, **использование сетевых ресурсов**, **управление памятью**, а также предоставляют информацию о системе, позволяют ожидать событий или создавать новые процессы.
|
||||
|
||||
Несмотря на важность системных вызовов, большинство программ редко работает с ними напрямую. Вместо этого они опираются на **библиотечные подпрограммы**, которые служат прослойкой между программой и ядром ОС. Отдельные системные вызовы могут блокировать выполнение процесса до тех пор, пока не будет выполнено определенное условие или событие.
|
||||
|
||||
### Системные вызовы RISC-V
|
||||
|
||||
В архитектуре `RISC-V` системные вызовы осуществляются с помощью инструкции `ecall`, которая инициирует исключение, устанавливая регистр `mcause` в специфическое значение. Этот механизм позволяет программам взаимодействовать напрямую с операционной системой.
|
||||
|
||||
Для успешного выполнения системного вызова необходимо следовать соглашению **ABI (Application Binary Interface)**. Этот интерфейс определяет, как именно аргументы и результаты будут передаваться между процессом и ядром. Это соглашение в многом напоминает тот механизм, который используется при вызове обычных подпрограмм.
|
||||
|
||||
На практике это выглядит следующим образом:
|
||||
|
||||
- **Номер системного вызова** помещается в регистр `a7`.
|
||||
- Аргументы для этого вызова размещаются в регистрах `a0` до `a6`.
|
||||
- После выполнения системного вызова, результаты будут находиться в регистрах `a0` и `a1` (или в основной памяти)
|
||||
|
||||
- Все регистры в этом контексте сохраняют свое состояние, что гарантирует безопасное выполнение и возврат из системных вызовов.
|
||||
|
||||
### Жизненный цикл процесса
|
||||
|
||||

|
||||
|
||||
*Рис. 20. Механизм управления процессами в операционной системе.*
|
||||
|
||||
Операционная система поддерживает список всех процессов в системе, отслеживая их текущие статусы, такие как **"готов к выполнению" (ready)**, **"выполняется" (executing)**, **"ожидает" (waiting)**, и другие.
|
||||
|
||||
Когда процесс готов к выполнению, операционная система планирует его выполнение. Процесс получает определенное количество процессорного времени для выполнения своей задачи или работает до завершения.
|
||||
|
||||
Если процесс делает системный вызов, который не может быть немедленно удовлетворен (например, если он ждет доступа к диску или другому ресурсу), то процесс переходит в состояние **"ожидания"**. Он приостанавливается и ожидает, когда его запрос будет выполнен.
|
||||
|
||||
Как только запрос, ожидающий процесса, удовлетворен (например, когда ресурс становится доступным), процесс переходит обратно в состояние **"готовности"**. Теперь он готов к выполнению и ожидает своей очереди.
|
||||
|
||||
### Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=Q0XINgDHCZE) на видеозапись лекции
|
570
Lectures/18. Synchronization. Cache coherence.md
Normal file
570
Lectures/18. Synchronization. Cache coherence.md
Normal file
@@ -0,0 +1,570 @@
|
||||
# Лекция 18. Синхронизация. Когерентность кеш
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 18. Синхронизация. Когерентность кеш](#лекция-18-синхронизация-когерентность-кеш)
|
||||
- [Содержание](#содержание)
|
||||
- [Параллелизм уровня потоков](#параллелизм-уровня-потоков)
|
||||
- [Коммуникационные модели](#коммуникационные-модели)
|
||||
- [Синхронизация (необходима при процессах, которые выполняются параллельно)](#синхронизация-необходима-при-процессах-которые-выполняются-параллельно)
|
||||
- [Потокобезопасное программирование](#потокобезопасное-программирование)
|
||||
- [Синхронная связь](#синхронная-связь)
|
||||
- [Буфер FIFO(First input, first output)](#буфер-fifofirst-input-first-output)
|
||||
- [Буфер FIFO с общей памятью](#буфер-fifo-с-общей-памятью)
|
||||
- [Семафоры](#семафоры)
|
||||
- [Семафоры для приоритета](#семафоры-для-приоритета)
|
||||
- [Семафоры для распределения ресурсов](#семафоры-для-распределения-ресурсов)
|
||||
- [Буфер FIFO с семафорами](#буфер-fifo-с-семафорами)
|
||||
- [Одновременные транзакции](#одновременные-транзакции)
|
||||
- [Семафоры для взаимных исключений](#семафоры-для-взаимных-исключений)
|
||||
- [Проблемы атомарности](#проблемы-атомарности)
|
||||
- [Мощность семафора](#мощность-семафора)
|
||||
- [Реализация семафоров](#реализация-семафоров)
|
||||
- [Синхронизация : обратная сторона](#синхронизация--обратная-сторона)
|
||||
- [Обедающие философы](#обедающие-философы)
|
||||
- [Решение](#решение)
|
||||
- [Исправленный метод передачи на основе вышеописанного алгоритма с избежанием тупика](#исправленный-метод-передачи-на-основе-вышеописанного-алгоритма-с-избежанием-тупика)
|
||||
- [Многоядерность](#многоядерность)
|
||||
- [Когерентность кэш](#когерентность-кэш)
|
||||
- [Поддержание когерентности](#поддержание-когерентности)
|
||||
- [Реализация когерентности](#реализация-когерентности)
|
||||
- [Snooping-Based Coherence](#snooping-based-coherence)
|
||||
- [Протокол Valid/Invalid (**VI**)](#протокол-validinvalid-vi)
|
||||
- [Modified/Shared/Invalid (MSI) протокол](#modifiedsharedinvalid-msi-протокол)
|
||||
- [MSI протокол FSM](#msi-протокол-fsm)
|
||||
- [Оптимизация MSI: состояние E](#оптимизация-msi-состояние-e)
|
||||
- [MESI: усовершенствованный](#mesi-усовершенствованный)
|
||||
- [Когерентность кэш и ложное совместное использование](#когерентность-кэш-и-ложное-совместное-использование)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
|
||||
## Параллелизм уровня потоков
|
||||
|
||||
**Поток** — это минимальная неделимая программная единица, которой операционная система выделяет процессорное время.
|
||||
**Параллелизм уровня потоков** — это разделение вычислений между несколькими исполнительными потоками, которые могут быть:
|
||||
|
||||
- несколькими независимыми последовательными потоками, которые конкурируют за общие ресурсы, такие как память, устройства ввода/вывода;
|
||||
- несколькими взаимодействующими последовательными потоками, которые взаимодействуют друг с другом.
|
||||
|
||||
То есть в рамках одной задачи может быть несколько потоков, они могут либо конкурировать за общие ресурсы, либо дожидаться друг друга, требовать синхронизации.
|
||||
|
||||
Существует две основные коммуникационные модели:
|
||||
|
||||
- общая память;
|
||||
- обмен.
|
||||
|
||||
### Коммуникационные модели
|
||||
|
||||
В коммуникационной моделью с общей памятью есть:
|
||||
|
||||
- есть единое адресное пространство для потоков;
|
||||
- общение между потоками происходит через неявную связь с помощью загрузки и сохранения в память.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Коммуникационная модель с общей памятью.*
|
||||
|
||||
В коммуникационной моделью с обменом сообщениями присутствуют:
|
||||
|
||||
- разделенное адресное пространство (у каждого из процессоров своя память);
|
||||
- общение между потоками происходит явной связи путем отправки и получения сообщений.
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Коммуникационная модель с обменом сообщениями.*
|
||||
|
||||
В плане реализации коммуникационная модель с общей памятью намного проще нежели коммуникационная модель с обменом сообщениями. Однако у первой модели существует риск возникновения гонок, в связи с чем требуется осуществлять синхронизацию.
|
||||
Дальше мы сосредоточимся на общей памяти и обсудим как происходит синхронизация.
|
||||
|
||||
### Синхронизация (необходима при процессах, которые выполняются параллельно)
|
||||
|
||||
Необходимость в синхронизации возникает каждый раз, когда в системе существуют параллельные процессы.
|
||||
|
||||
- Вилки и соединения (fork and join): параллельный процесс должен подождать, пока не произойдёт несколько событий.
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Способ синхронизации параллельных процессов "Вилки и соединения" (fork and join).*
|
||||
|
||||
Рассмотрим ситуацию, когда процесс порождает два параллельных потока `P₁` и `P₂` и впоследствии использует результаты их вычислений. После создания, процесс сможет продолжить дальнейшее выполнение только когда будут выполнены оба потока, а значит есть необходимость их синхронизировать.
|
||||
|
||||
- Проиводитель-потребитель (producer-consumer): потребительский процесс должен ждать, пока процесс производителя не произведет данные (то есть потребитель не может продолжать выполнение, пока производитель не произведёт какие-то данные).
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Способ синхронизации параллельных процессов "Проиводитель-потребитель" (producer-consumer).
|
||||
|
||||
- **Взаимное исключение**: операционная система должна гарантировать, что ресурс используется только одним процессом в данный момент времени (например, два процесса не могут одновременно обращаться к одной ячейке памяти).
|
||||
|
||||
## Потокобезопасное программирование
|
||||
|
||||
Многопоточные программы могут выполняться на одном процессоре с помощью **таймшеринга** (технология, обеспечивающая разделение ресурсов одного большого компьютера между несколькими пользователями, выделяя каждому из них определенное время доступа к ресурсам).
|
||||
|
||||
- Каждый поток выполняется некоторое время (например до очередного прерывания по таймеру), после чего ОС переключается на другой поток и все повторяется заново.
|
||||
|
||||
**Потокобезопасные** многопоточные программы ведут ведут себя одинаково независимо от того, выполняются ли они на нескольких процессорах или на одном процессоре.
|
||||
|
||||
- Мы будем предполагать, что каждый поток имеет свой собственный процессор для запуска.
|
||||
|
||||
## Синхронная связь
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Пример программы с синхронной связью.
|
||||
|
||||
Метка `loop` указывает на последовательность инструкций xxxᵢ, которые генерируют данные `с`. После этого производитель оправляет эти данные для потребителя и потом возвращается к началу цикла и так далее. В свою очередь потребитель получает данные (receive) от производителя, выполняет над ними нужные операции и снова возвращается к началу цикла.
|
||||
|
||||
**Приоритет очерёдности** `a`⩽`b`,`a` предшествует `b`:
|
||||
|
||||
- Потребитель не может использовать данные до их получения (событие sendᵢ должно происходить раньше или в тот же момент времени, когда происходит `rcvᵢ` (получение) этих данных);
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Пример программы с синхронной связью c учётом приоритета очерёдности.
|
||||
|
||||
- Производитель не может перезаписать данные до их использования потребителем (получение данных должно происходить раньше, чем их перезапишет следующая `i+1` посылка).
|
||||
|
||||
### Буфер FIFO(First input, first output)
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Пример буфера FIFO без ограничений приоритета.
|
||||
|
||||
Буфер FIFO ослабляет ограничения, связанные с синхронизацией. Производитель может опередить потребителя на `N` значений (где N — глубина данного буфера).
|
||||
|
||||
`rcvᵢ` ≤ `sendᵢ₊₁`
|
||||
|
||||
Обычно реализуется как кольцевой буфер в общей памяти:
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Пример кольцевого буфера без ограничений приоритета с указателями на начало и конец очереди.
|
||||
|
||||
У нас есть буфер на 3 элемента (очередь) и два указателя: один указывает на место, куда мы будем писать (`write_ptr`), а другой указывает на место, откуда мы будем читать (`read_ptr`). В очередной момент времени происходит генерация новых данных (`send c₀`) — они записываются в место, куда указывает `write_ptr`. После этого данный указатель сдвигается на одну ячейку вправо (`i+1`). Далее мы снимаем данные с первой ячейки (`rcv()`) c₀ и указатель `read_ptr` сдвигается на следующую ячейку (`c₁`) и так далее.
|
||||
|
||||
### Буфер FIFO с общей памятью
|
||||
|
||||

|
||||
|
||||
*Рис. 9. Пример программы буфера FIFO с общей памятью без ограничений приоритета.
|
||||
|
||||
Данный буфер **не применяет никаких ограничений приоритета** (*например, `rcv()` может быть вызван до любой отправки*) и поэтому работает неправильно. Чтобы устранить эту проблему, нам поможет концепция *семафоров*.
|
||||
|
||||
### Семафоры
|
||||
|
||||
Семафоры — это программная конструкция для синхронизации.
|
||||
|
||||
Semaphore — это тип данных, число ≥ 0.
|
||||
Объявляется следующим образом : semaphore `s` = `K`; // инициализируем `s` значением `K`.
|
||||
|
||||
Операции, которые определены для семафоров:
|
||||
|
||||
- wait (semaphore s) - ждёт если семафор `s` == 0 (если в момент времени, когда мы доходим до операции wait, семафор = 0 — программа останавливает свою работу на этой строчке и не двигается дальше), как только семафор стал > 0 программа идёт дальше, а сам семафор уменьшается на 1: `s` = `s` - 1;
|
||||
- signal (semaphore s) - каждый раз когда программа проходит эту операцию, семафор увеличивается на 1: `s` = `s` + 1 (один ожидающий поток теперь может быть в состоянии продолжить).
|
||||
|
||||
Семантические гарантии: семафор `s` инициализированный как `K`, применяет ограничение приоритета:
|
||||
|
||||
`signal(s)ᵢ` < `wait(s)ᵢ₊ₖ`,`i`-ый вызов `signal(s)` должен завершиться до завершения `(i+K)` вызова `wait(s)`.
|
||||
|
||||
### Семафоры для приоритета
|
||||
|
||||
Нам нужно, чтобы оператор `А₂` в потоке `А` был завершён до того. как начнётся оператор `B₄` в потоке `B`:
|
||||
`А₂` < `B₄`
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Потоки `А` и `B` .
|
||||
|
||||
Решение:
|
||||
|
||||
- объявить `semaphore` = 0;
|
||||
- `signal(s)` в начале стрелки (после `A₂>A`);
|
||||
- `wait(s)` в конце стрелки.
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Потоки `A` и `B` с семафорами для приоритета.
|
||||
|
||||
Если мы в потоке B придём раньше до `B₄`, то `s` по умолчанию = 0 и мы застрянем на инструкции `wait(s)`. В это время первый поток А доходит до `signal(s)`, то есть увеличивает `s` на 1, соответственно внутри `wait` `s` тоже увеличилось на 1. Мы прошли этот `wait` и семафор снова стал нулём.Таким образом, мы получили синхронизацию, которую хотели.
|
||||
|
||||
### Семафоры для распределения ресурсов
|
||||
|
||||
Описание проблемы:
|
||||
|
||||
1) существует `K` ресурсов;
|
||||
2) существует множество потоков, каждый из которых нуждается в ресурсах в случайные моменты времени;
|
||||
3) необходимо гарантировать, что в любой момент времени используется не более `K` ресурсов.
|
||||
|
||||
Решение с использованием семафоров:
|
||||
|
||||
- В основной памяти : `semaphore s` = `K`;//`K` ресурсов;
|
||||
- Используемые ресурсы
|
||||
`wait(s)`;//выделение ресурса
|
||||
...//использование его некоторое время
|
||||
`signal(s)`;//возвращение ресурса.
|
||||
|
||||
То есть если количество `wait` произойдет столько же раз сколько и `K`, то мы обнулим этот ресурс и очередной `wait` не даст нам повторно использовать этот ресурс.
|
||||
|
||||
### Буфер FIFO с семафорами
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Пример программы буфера FIFO с семафорами.
|
||||
|
||||
- выполняется приоритет, управляемый семафором `sendᵢ` ≤ `revᵢ`;
|
||||
- здесь есть один ресурс, управляемый семафором: количество символов в буфере;
|
||||
- всё ещё некорректная ситуация, так как производитель может переполнить буфер;
|
||||
- должны применять требование `rcvᵢ` ≤ `sendᵢ₊₁>`.
|
||||
|
||||

|
||||
|
||||
*Рис. 13. Пример программы буфера FIFO с семафорами с применением требования `rcvᵢ` ≤ `sendᵢ₊₁.`
|
||||
|
||||
Ресурсы, управляемые семафорами: символы в FIFO, свободное место в FIFO.
|
||||
Работает с одним производителем и потребителем.
|
||||
|
||||
### Одновременные транзакции
|
||||
|
||||
Предположим, что вы и ваш друг посещаете банкомат в одно и то же время и снимаете 100 рублей со своего счёта. Что происходит?
|
||||
|
||||

|
||||
|
||||
*Рис. 14. Код к конкретной задаче.
|
||||
|
||||
Результат: у вас есть 200 рублей и баланс счёта уменьшился на 200 рублей.
|
||||
|
||||
Представим, что когда первый поток начал выполняться, второй поток начал делать то же самое, то есть они немного перекрылись. Значит, когда потоки будут уменьшать баланс, они будут уменьшать одно и то же значение.
|
||||
|
||||

|
||||
|
||||
*Рис. 15. Перекрытие потоков.
|
||||
|
||||
Результат: у вас есть 200 рублей, а баланс счёта уменьшился на 100 рублей.
|
||||
|
||||
Необходимо быть осторожным при написании параллельных программ. В частности, при изменении общих данных.
|
||||
Для некоторых сегментов кода, называемых критическими секциями (**critical sections**) мы хотели бы убедиться, что никакие два выполнения не перекрываются.
|
||||
Это ограничение называется взаимным исключением (**mutual exclusion**).
|
||||
|
||||
**Решение**: внедрить в критические секции обёртки, которые гарантируют **атомарность**, то есть делают их похожими но отдельные мгновенные операции.
|
||||
|
||||
### Семафоры для взаимных исключений
|
||||
|
||||

|
||||
|
||||
*Рис. 16. Функция из предыдущего примера.
|
||||
|
||||
Нам нужно гарантировать, что двойной вызов функции `debit` не пересекается. То есть либо `a` предшествует `b`, либо `b` предшествует `a` (они не пересекаются!).
|
||||
|
||||
Для этого:
|
||||
|
||||
- берём семафор `semaphore lock`, инициализируем его единицей;
|
||||
- вначале функции ставим `wait(lock)`, то есть вначале мы его блокируем;
|
||||
- в конце ставим `signal(lock)`, снимаем блокировку.
|
||||
|
||||

|
||||
|
||||
*Рис. 17. Итоговая функция с семафором для взаимных исключений.
|
||||
|
||||
### Проблемы атомарности
|
||||
|
||||
Рассмотрим несколько потоков производителей:
|
||||
Два потока могут генерировать данные для нашего `consumer` и может возникнуть ситуация, когда сначала один поток поместил в общий буфер `char`, но ещё не успел обновить указатель, и в этот момент времени второй поток загружает свой символ в буфер просто перезаписав значение, то есть производители мешают друг другу, а этого не должно быть.
|
||||
|
||||

|
||||
|
||||
*Рис. 18. Потоки производители для нашего примера.
|
||||
|
||||
Справиться с этим помогут наши блокировки:
|
||||
|
||||

|
||||
|
||||
*Рис. 19. Программа буфера FIFO с блокировками.
|
||||
|
||||
### Мощность семафора
|
||||
|
||||
Семафор — это единый примитив синхронизации, обеспечивающий:
|
||||
|
||||
- Отношение приоритета;
|
||||
- `sendᵢ` ≤ `rcvᵢ` (событие `send<sub>i </sub>` должно происходить раньше или в тот же момент времени, когда происходит `rcvᵢ`(полупение) этих данных);
|
||||
- `rcvᵢ` ≤ `sendᵢ₊₁` (получение данных должно происходить раньше, чем их перезапишет следующая `i+1` посылка).
|
||||
- Отношение взаимного исключения;
|
||||
- Защита переменных `in` и `out`.
|
||||
|
||||
Пример с синхронизированными потоками:
|
||||
|
||||

|
||||
|
||||
*Рис. 20. Итоговая программа буфера FIFO с блокировками для защиты переменных `in` и `out`.
|
||||
|
||||
### Реализация семафоров
|
||||
|
||||
Семафоры сами по себе являются общими данными, и для реализации операций `wait` и `signal` требуются последовательности чтения /изменения /записи, которые должны выполняться как критические секции (то есть фактически семафор это такое же число в памяти, его нужно сначала загрузить, потом выполнить нужное действие и затем загрузить обратно в память).
|
||||
Для взаимного исключения в этих конкретных критических секциях без использования семафоров можно:
|
||||
|
||||
- Использовать специальную инструкцию (например, "test and set"), которая выполняет атомарное чтение-изменение-запись. Зависит от атомарности выполнения одной команды. Это самый распространённый подход.
|
||||
- Реализуется с помощью системных вызовов. Работает только в однопроцессорных системах, где ядро бесперебойно.
|
||||
|
||||
### Синхронизация : обратная сторона
|
||||
|
||||
Использование ограничений синхронизации может привести к возникновению собственного набора проблем, особенно когда потоку требуется доступ к нескольким защищенным ресурсам.
|
||||
Представим ситуацию, когда два человека пересылают друг другу одновременно `N`-ую сумму денег:
|
||||
|
||||

|
||||
|
||||
*Рис. 21. Пересылка одинаковой суммой денег с одного счёта на другой.
|
||||
|
||||

|
||||
|
||||
*Рис. 22. Функция пересылки денег.
|
||||
|
||||
Что же может пойти не так?
|
||||
Thread 1: wait (lock [0903]); (поток 1 блокирует 0903)
|
||||
|
||||
Thread 2: wait (lock [1103]); (поток 2 параллельно блокирует 1103)
|
||||
|
||||
Thread 1: wait (lock [1103]); //не завершиться, пока не произойдёт signal 2 потока (заблокирован, потому что предыдущий поток его уже заблокировал, кончился ресурс)
|
||||
|
||||
Thread 1: wait (lock [0903]); //не завершиться, пока не произойдёт signal 1 потока.
|
||||
|
||||
Ни один поток не может добиться прогресса - это называется **Тупик** или **Deadlock**.
|
||||
**Deadlock** — ситуация, при которой несколько процессов находятся в состоянии ожидания ресурсов, занятых друг другом, и ни один из них не может продолжать свое выполнение.
|
||||
|
||||
### Обедающие философы
|
||||
|
||||

|
||||
|
||||
*Рис. 23. Карикатура обедающих философов за столом.
|
||||
|
||||
Философы мыслят глубокими мыслями, но имеют простые мирские потребности. Когда вы голодны, группа из `N` философов будет сидеть вокруг стола с N палочками для еды, разбросанными между ними. Еда подаётся, и каждый философ наслаждается неторопливой едой, используя палочки для еды с обеих сторон.
|
||||
Они очень вежливы и терпеливы, и каждый соблюдает обеденный протокол.
|
||||
Алгоритмы философа:
|
||||
|
||||
- взять (дождаться) ЛЕВУЮ палочку;
|
||||
- взять (дождаться) ПРАВУЮ палочку;
|
||||
- кушать, пока не насытится;
|
||||
- заменить обе палочки.
|
||||
|
||||
Никто не может добиться прогресса, потому что все они ждут недоступного ресурса.
|
||||
Условия:
|
||||
|
||||
1) Взаимное исключение: только один поток может содержать ресурс в данный момент времени;
|
||||
2) Удержание и ожидание: поток удерживает выделенные ресурсы, ожидая других;
|
||||
3) Отсутствие вытеснения: ресурс не может быть удалён из потока, удерживающего его;
|
||||
4) Происходит круговое ожидание.
|
||||
|
||||
### Решение
|
||||
|
||||
Назначить уникальный номер каждой палочке для еды. Запрашивать ресурсы в последовательном порядке (алгоритм Дейкстры).
|
||||
|
||||
Новый алгоритм:
|
||||
|
||||
- Взять палочку с МЕНЬШИМ номером;
|
||||
- Взять палочку с БОЛЬШИМ номером;
|
||||
- ЕСТЬ;
|
||||
- Заменить ОБЕ палочки.
|
||||
|
||||

|
||||
|
||||
*Рис. 24. Решение проблемы обедающих философов.
|
||||
|
||||
Доказательство: `Deadlock` означает, что каждый философ ждёт ресурса, которым владеет какой-то другой философ. Но философ, держащий самую большую палочку для еды не может ждать какого-либо другого философа.
|
||||
|
||||
### Исправленный метод передачи на основе вышеописанного алгоритма с избежанием тупика
|
||||
|
||||

|
||||
|
||||
*Рис. 25. Исправленный метод передачи денежной суммы.
|
||||
|
||||
## Многоядерность
|
||||
|
||||

|
||||
|
||||
*Рис. 26. Многоядерность.
|
||||
|
||||
1. Современные процессоры обычно имеют от 2 до 8 ядер, где каждое ядро имеет собственный кэш для повышения производительности.
|
||||
2. Ядро могут использоваться совместно для ускорения работы приложения.
|
||||
3. Ядра могут взаимодействовать друг с другом через память.
|
||||
|
||||
## Когерентность кэш
|
||||
|
||||
Необходимо создать иллюзию единой общей памяти, даже если многоядерные системы имеют несколько приватных (собственных) кэшей (если они обновляют информацию, то эта информация должна быть доступна всем кэшам, которые её используют).
|
||||
|
||||
Проблема:
|
||||
|
||||

|
||||
|
||||
*Рис. 27. Проблема многоядерности.
|
||||
|
||||
1) Ядро 0 загружает данные из памяти по адресу `A` число два.
|
||||
2) Ядро 2 выгружает в память по адресу `A` число три.
|
||||
3) Нулевое ядро после этого опять загружает данные по этому же адресу, но в кэше лежат старые данные.
|
||||
|
||||
То есть процессор получит данные из кэша, но эти данные не соответствуют действительности, так как другое ядро обновило эти данные.
|
||||
|
||||
Решение: протокол когерентности кэша контролирует содержимое кэша, чтобы избежать устаревших строк.
|
||||
|
||||
Например, сделать копию `A` ядра 0 недействительной, прежде чем позволить ядру 2 писать в него.
|
||||
|
||||
### Поддержание когерентности
|
||||
|
||||
В когерентной памяти все загрузки и сохранения размещаются в глобальном порядке.
|
||||
Несколько копий адреса в различных кэшах могут привести к нарушению этого свойства.
|
||||
Это свойство может быть обеспечено, если:
|
||||
|
||||
- Только один кэш одновременно имеет разрешение на запись;
|
||||
- Никакой кэш не может иметь устаревшую копию данных после того, как была выполнена запись по адресу.
|
||||
|
||||
### Реализация когерентности
|
||||
|
||||
Протоколы когерентности должны обеспечивать соблюдение двух правил:
|
||||
|
||||
- распространяющаяся запись (**Write propagation**): записи в конечном итоге становятся видимыми для всех процессоров (если кто-то из процессоров пишет куда-то, то нужно однозначно остальным об этом сообщить);
|
||||
сериализация записи (**Write serialization**): записи в одно и то же место сериализуются (все процессоры видят их в том же порядке).
|
||||
|
||||
Как обеспечить распространение записи:
|
||||
|
||||
- **write-invalidate protocols**: аннулировать все другие кэшированные копии перед выполнением записи;
|
||||
- **write-update protocols**: обновить все другие кэшированные копии после выполнения записи.
|
||||
|
||||
Как обеспечить сериализацию записи:
|
||||
|
||||
- **snooping-based protocols**: все кэши наблюдают за действиями друг друга через общую шину;
|
||||
- **directory-based protocols**: каталог когерентности отслеживает содержимое частных кэшей и сериализует запросы.
|
||||
|
||||
### Snooping-Based Coherence
|
||||
|
||||
Кэширует слежение за шиной (отслеживание), чтобы все процессоры могли видеть память согласованной.
|
||||
|
||||

|
||||
|
||||
*Рис. 28. Процессоры со `Snoopy Cache`, которые подключены к основной памяти.
|
||||
|
||||
То есть каждый раз, когда процессор обращается к кэш памяти, он выставляет информацию на общую шину. И все кэши видят когда кто-то на эту шину выставляет информацию.
|
||||
|
||||
Шина обеспечивает задачу сериализации:
|
||||
|
||||
- Широковещательный сигнал, полностью упорядоченный.
|
||||
- Каждый кэш-контроллер "шпионит" за всеми транзакциями на шине.
|
||||
- Контроллер обновляет состояние кэша в ответ на запросы процессора и snoop-события и генерирует транзакции на шине.
|
||||
|
||||
Snoopy кэш отличается от обычного кэша наличием дополнительного поля `State` (состояние) и контроллером, который следит за шиной и содержимым состояния каждой записи.
|
||||
|
||||
В ячейку `State` может быть записан один дополнительный бит (0 или 1). Этот бит указывает, на валидность или не валидность записи исходя из когерентности данных в кэше.
|
||||
|
||||

|
||||
|
||||
*Рис. 29. Упрощенная форма `Snoopy Cache`.
|
||||
|
||||
**Snoopy протокол (FSM)** — это конечный автомат, который зависит от того что происходит на шине и обновляет значения состояния.
|
||||
|
||||
- Диаграмма состояний переходов.
|
||||
- Действия.
|
||||
|
||||
### Протокол Valid/Invalid (**VI**)
|
||||
|
||||
Поддерживается только кэшем со сквозной записью (нужно чтобы все видели что происходит на шине).
|
||||
|
||||

|
||||
|
||||
*Рис. 30. Протокол `VI`.
|
||||
|
||||
Когда мы находимся в состоянии `Invalid`, и какое-то ядро запрашивает данные, то происходит `Processor Read` (PrRd). Затем он получает данные в свой кэш и выставляет эти данные как `Valid`.
|
||||
В какой-то момент это ядро видит, что какое-то ядро записало по этому адресу (то есть на шине произошла запись `Bus Write`), тогда оно сразу меняет состояние этой ячейки на `Invalid`, потому что в этот момент времени у него неактуальные данные.
|
||||
|
||||

|
||||
|
||||
*Рис. 31. Основные действия для данного протокола.
|
||||
|
||||
Таким образом, если мы читаем данные, то мы переходим в состояние `Valid`.Если мы видим, что какое-то ядро записывает по этому адресу, то переходим в состояние `Invalid`.
|
||||
|
||||
Пример:
|
||||
|
||||

|
||||
|
||||
*Рис. 32. Пример применения протокола `Valid/Invalid`.
|
||||
|
||||
1) Допустим, ядро 0 сначала загружаю по адресу `A`. На шине запрашивается чтение, в кэш попадает запись с состоянием `Valid`.
|
||||
2) Затем загружается второе ядро по адресу `A`, теперь там тоже запись `Valid`.
|
||||
3) Теперь происходит запись числа в память, кэш видит это и делает `Invalidate` данных (обнуляет их).
|
||||
4) Когда произойдёт очередной `load`, он увидит, что мы находимся в состоянии `Invalidate`.
|
||||
5) Теперь просто зачитаем обновленные данные.
|
||||
|
||||

|
||||
|
||||
*Рис. 33. Пример применения протокола `Valid/Invalid` с пояснениями.
|
||||
|
||||
Проблемы `VI`:
|
||||
|
||||
- каждая запись обновляет основную память;
|
||||
- каждая запись требует широковещательной передачи и слежки.
|
||||
|
||||
### Modified/Shared/Invalid (MSI) протокол
|
||||
|
||||
Каждая строка в каждом кэше поддерживает `MSI` состояния:
|
||||
|
||||
- `I`-кэш не содержит адреса;
|
||||
- `S`-кэш содержит адрес, но он так же может находится в других кэшах, следовательно он может быть только прочитан;
|
||||
- `M`-кэш содержит этот адрес, следовательно он может быть и прочитан и записан — любой другой кэш имевший этот адрес будет признан недействительным (то есть как только запишется по этому адресу все остальные аннулируют информацию об этом).
|
||||
|
||||
### MSI протокол FSM
|
||||
|
||||
Если процессор считывает данные (PrRd), то тогда на шине появляется значение, что мы читаем данные (`BusRd`) и мы переходим в состояние `S`.
|
||||
|
||||
Если мы увидим, что где-то происходит эксклюзивное чтение данных для записи этих данных (`BusRdX`), то мы перейдём в состояние `Invalidate` (потому что данные больше не актуальны).
|
||||
|
||||
Если же мы находимся в состоянии `Invalidate` и процессор хочет осуществить запись в какую-либо ячейку памяти, то шина об этом конечно узнает, потому что мы запрашиваем эксклюзивное пользование данными (`BusRdX`), и мы перейдём в состояние `M`. Дальше происходит чтение и запись данных. Если мы находимся в состоянии `M` и кто-то прочитает данные, то мы автоматически перейдём в состояние чтения (`S`).
|
||||
|
||||

|
||||
|
||||
*Рис. 34. `MSI` протокол.
|
||||
|
||||

|
||||
|
||||
*Рис. 35. Основные действия для данного протокола.
|
||||
|
||||
- Недостатки `VI`: каждая запись обновляет основную память, и каждая запись требует широковещательной передачи и слежки.
|
||||
- `MSI`: возможность реализации кэша с обратной записью (`writeback`) + удовлетворяет локальную запись.
|
||||
|
||||
### Оптимизация MSI: состояние E
|
||||
|
||||
Наблюдение: выполнение последовательной чтения-изменения-записи на частных данных является обычным делом.
|
||||
|
||||
В чём проблема `MSI`?
|
||||
|
||||
- Две данные транзакции для каждого чтения-изменения-записи частных данных.
|
||||
|
||||
Решение: `Е-состояние` (`Exclusive`)
|
||||
|
||||
- Если данные ни с кем не разделяются, то чтение переводит строку в состояние `E` вместо состояния `S`.
|
||||
- Запись не вещается на шину, потому что `E` → `M` (`exclusive`).
|
||||
|
||||
### MESI: усовершенствованный
|
||||
|
||||
Каждая строка в кэше содержит тег и биты состояния:
|
||||
|
||||
- `M`: `Modified Exclusive`.
|
||||
- `E`: `Exclusive, unmodified`.
|
||||
- `S`: `Shared`.
|
||||
- `I`: `Invalid`.
|
||||
|
||||

|
||||
|
||||
*Рис. 36. Протокол `MESI`: усовершенствованный.
|
||||
|
||||
### Когерентность кэш и ложное совместное использование
|
||||
|
||||
Строка кэша содержит более одного слова, и согласованность кэша выполняется на уровне детализации строки.
|
||||
|
||||

|
||||
|
||||
*Рис. 37. Строка кэша.
|
||||
|
||||
Предположим `P₁` записывает `wordᵢ` и `P₂` записывает `wordₖ` и оба слова имеют один и тот же адрес строки.
|
||||
Что может произойти?
|
||||
|
||||
Из-за того что присутствуют алгоритмы когерентности, будет происходить *пинг-понг*.
|
||||
Строка может быть недействительной (*пинг-понг*) много раз без необходимости, потому что адреса находятся в одной строке.
|
||||
|
||||
### Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=wr7KuOSPP5I&list=PL0def37HEo5KHPjwK7A5bd4RJGg4djPVf&index=26) на видеозапись лекции
|
||||
2. [Ссылка](https://onedrive.live.com/?authkey=!AIXUSz0MyutL6hs&id=1FF28DEC684C2C56!81692&cid=1FF28DEC684C2C56) на лекцию в формате Power Point
|
301
Lectures/20. Input-Output System.md
Normal file
301
Lectures/20. Input-Output System.md
Normal file
@@ -0,0 +1,301 @@
|
||||
# Лекция 20. Ввод\Вывод
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 20. Ввод\\Вывод](#лекция-20-вводвывод)
|
||||
- [Содержание](#содержание)
|
||||
- [Системы ввода-вывода](#системы-ввода-вывода)
|
||||
- [Система ввода-вывода подключена к центральному процессору с помощью отдельной шины](#система-ввода-вывода-подключена-к-центральному-процессору-с-помощью-отдельной-шины)
|
||||
- [Система ввода-вывода имеет отдельную от памяти шину управления, но совместную шину адреса и данных](#система-ввода-вывода-имеет-отдельную-от-памяти-шину-управления-но-совместную-шину-адреса-и-данных)
|
||||
- [Система ввода-вывода имеет единую шину с основной памятью](#система-ввода-вывода-имеет-единую-шину-с-основной-памятью)
|
||||
- [Адресное пространство](#адресное-пространство)
|
||||
- [Системы с выделенным адресным пространством](#системы-с-выделенным-адресным-пространством)
|
||||
- [Системы с совмещенным (совместным) адресным пространством](#системы-с-совмещенным-совместным-адресным-пространством)
|
||||
- [Структура периферийного устройства](#структура-периферийного-устройства)
|
||||
- [Модули ввода-вывода](#модули-ввода-вывода)
|
||||
- [Ввод-вывод с опросом](#ввод-вывод-с-опросом)
|
||||
- [Ввод-вывод с прерываниями](#ввод-вывод-с-прерываниями)
|
||||
- [Прямой доступ к памяти (ПДП или Direct Memory Access — DMA)](#прямой-доступ-к-памяти-пдп-или-direct-memory-access--dma)
|
||||
- [Конфигурации ПДП(DMA)](#конфигурации-пдпdma)
|
||||
- [Канальная система ввода-вывода](#канальная-система-ввода-вывода)
|
||||
- [RAID](#raid)
|
||||
- [JTAG (Join Test Action Group)](#jtag-join-test-action-group)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
- [Дополнительные материалы к лекции](#дополнительные-материалы-к-лекции)
|
||||
|
||||
## Системы ввода-вывода
|
||||
|
||||
> *Система ввода-вывода* — это комплекс обмена информацией с внешними устройствами.
|
||||
|
||||
К системе ввода-вывода можно отнести и способы подключения к системной шине различного оборудования, и процедуры взаимодействия процессора с этим оборудованием, и команды процессора, предназначенные для обмена данными с внешними устройствами.
|
||||
|
||||
Системы ввода-вывода различают по способам подключения к процессору.
|
||||
|
||||
### Система ввода-вывода подключена к центральному процессору с помощью отдельной шины
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Отдельная шина системы ввода-вывода.*
|
||||
|
||||
- Плюсы: система ввода-вывода отделена от основной памяти и для нее может быть соблюдена своя специфика, например меньшие скорости, определенный интерфейс работы, который больше подходит под данные системы.
|
||||
- Минусы: много точек подключения, меньшая надежность, большие габариты и т.д.
|
||||
|
||||
### Система ввода-вывода имеет отдельную от памяти шину управления, но совместную шину адреса и данных
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Система ввода-вывода с отдельной шиной управления.*
|
||||
|
||||
- Плюсы: специализация под систему ввода-вывода (т.к. управление осуществляется по другой линии), используются отдельные инструкции для работы с вводом-выводом.
|
||||
|
||||
Архитектура x86 использует данный тип подсистемы ввода-вывода.
|
||||
|
||||
### Система ввода-вывода имеет единую шину с основной памятью
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Единая шина для системы ввода-вывода и памяти.*
|
||||
|
||||
- Плюсы: в случае совместного адресного пространства мы имеем гибкий размер системы ввода-вывода (то есть мы можем уменьшить количество памяти и увеличить количество систем ввода-вывода или наоборот).
|
||||
- Минусы: поскольку для доступа к регистрам модулей ввода-вывода используется та же шина, что и для доступа к памяти, процессор использует в обоих случаях одни и те же инструкции, что отрицательно сказывается на читаемости ассемблерного кода.
|
||||
|
||||
Архитектуры RISC-V и MIPS используют данный тип подсистемы ввода-вывода.
|
||||
|
||||
## Адресное пространство
|
||||
|
||||
> *Адресное пространство* — совокупность всех допустимых адресов каких-либо объектов вычислительной системы.
|
||||
|
||||
Системы ввода-вывода различают по организации адресного пространства.
|
||||
|
||||
### Системы с выделенным адресным пространством
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Системы с выделенным адресным пространством.*
|
||||
|
||||
В выделенном адресном пространстве ячейки памяти отделены от модулей ввода-вывода. То есть процессор имеет 2 шины. Одна направлена для памяти, другая для ввода-вывода.
|
||||
|
||||
Пример системы с выделенным адресным пространством приведен на рис. 1.
|
||||
|
||||
### Системы с совмещенным (совместным) адресным пространством
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Системы с совмещенным (совместным) адресным пространством.*
|
||||
|
||||
В совместном адресном пространстве есть только один набор адресов. Обращаясь по одним адресам мы попадаем в память, а по другим в управляющие регистры, которые ассоциированы с периферийными устройствами (т.е устройствами ввода-вывода, те которые подключаются к системе и связывают её с внешним миром).
|
||||
|
||||
Пример системы с совместным адресным пространством приведен на рис. 3.
|
||||
|
||||
При выделенном адресном пространстве можно разрабатывать систему ввода-вывода отдельно от памяти. В случае совместного этого не получится потому, что система ввода-вывода и память должны удовлетворять одним и тем же требованиям по связи (т.е. передачи информации).
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Совместное адресное пространство с дешифратором адреса.*
|
||||
|
||||
## Структура периферийного устройства
|
||||
|
||||
Все периферийные устройства можно свести к трём категориям:
|
||||
|
||||
- Для общения с пользователем (принтеры, мониторы и др.)
|
||||
- Для общения с вычислительной машиной (внешние устройства, которые отдают или получают информацию от внешнего мира через различные датчики, а также системы хранения информации)
|
||||
- Для связи с удаленными устройствами (передача информации на большие расстояния)
|
||||
|
||||
Обобщенно любое периферийное устройство можно представить в виде:
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Периферийное устройство.*
|
||||
|
||||
Периферийное устройство как-то взаимодействует с внешней средой. (Например датчик температуры. На преобразователь приходит температура, каким-то образом преобразуется и отправляется в буферную память в виде нолики и единички, которые характеризуют среду.)
|
||||
|
||||
Буферная память и логика управления связана с модулями ввода-вывода условными сигналами (условные так как для связи с модулями ввода-вывода используется 'малый' интерфейс).
|
||||
|
||||
Модуль ввода-вывода по данному интерфейсу генерирует различные сигналы управления для периферийного устройства, 'говоря' что нужно делать, и при этом собирает сигналы состояния, чтобы понимать в каком состоянии находится устройство (может быть у него какие-то проблемы или ошибки, закончило ли оно преобразование информации (например можно узнать храниться ли что-то в буферной памяти и можно ли это забирать)).
|
||||
|
||||
## Модули ввода-вывода
|
||||
|
||||
Основные функции модулей ввода-вывода:
|
||||
|
||||
- Локализация данных (выделение некоторого адресного пространства внутри которого процессор может через модуль ввода-вывода управлять периферийными устройствами).
|
||||
- Управление и синхронизация (модуль ввода-вывода с одной стороны подключен 'большим' интерфейсом к высокоскоростной шине, к которой также подключены память и процессор, а с другой стороны 'малым' интерфейсом к медленным устройствам (к периферии), у которых могут быть специфические сигналы управления и синхронизации).
|
||||
- Обмен информацией
|
||||
- Распознавание команд
|
||||
- Пересылка данных (от периферии в процессор либо в память и обратно)
|
||||
- Извещение о состоянии (извещение процессора о состоянии периферийных устройств)
|
||||
- Буферизация данных
|
||||
- Обнаружение ошибок (и извещение об этом процессора)
|
||||
|
||||
К одному модулю ввода-вывода может быть подключено много периферийных устройств, может быть много самих модулей ввода-вывода. В таком случае старшая часть адреса, которую выставляет процессор, указывает на конкретный модуль ввода-вывода, следующие несколько бит информации указывают на конкретное периферийное устройство, внутри этого модуля ввода-вывода, а последние биты указывают на конкретный регистр конкретного устройства.
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Структура модуля ввода-вывода.*
|
||||
|
||||
Модуль ввода-вывода — это прослойка между шиной и периферийными устройствами, у которой с одной стороны реализован контроллер 'большого' интерфейса, с другой стороны контроллеры 'малых' интерфейсов, а в середине некая логика управления, с помощью которой процессор может обмениваться информацией между интерфейсами.
|
||||
|
||||
Системы ввода-вывода различают по методу управления вводом-выводом.
|
||||
|
||||
### Ввод-вывод с опросом
|
||||
|
||||
- Плюсы: простота.
|
||||
- Минусы: процессор постоянно занимает шину; процессор не делает ничего полезного, он занят ожиданием устройства ввода, которое может генерировать информацию миллионы тактов процессора.
|
||||
|
||||
Процессор получает данные от периферийного устройства по следующей схеме:
|
||||
|
||||

|
||||
|
||||
*Рис. 9. Алгоритм ввода-вывода с опросом.*
|
||||
|
||||
### Ввод-вывод с прерываниями
|
||||
|
||||
- Плюсы: процессор не ждет периферия сгенерирует новую информации.
|
||||
- Минусы: процессору приходится перекидывать информацию в основную память через себя.
|
||||
|
||||
Метод состоит из двух частей:
|
||||
|
||||
- Инициализация прерывания (сообщить модулю ввода-вывода, что мы ждем информацию от какого-то периферийного устройства, после чего разрешаем прерывания от этого модуля ввода-вывода).
|
||||
- Обработка прерывания (процесс просыпается и начинает читать из регистра состояний модули ввода-вывода).
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Алгоритм ввода-вывода с прерываниями.*
|
||||
|
||||
### Прямой доступ к памяти (ПДП или Direct Memory Access — DMA)
|
||||
|
||||
- Плюсы: процессор не занимается пересылкой данных.
|
||||
- Минусы: сложность реализации в высокопроизводительных системах с виртуальной и кэш памятью.
|
||||
|
||||
Контроллер прямого доступа к памяти — это устройство, которое берет на себя задачу переброски информации из периферийных устройств в основную память либо наоборот из основной памяти в периферийное устройство в обход процессора.
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Схема с контроллером прямого доступа к памяти.*
|
||||
|
||||
Получение доступа к шине КПДП:
|
||||
|
||||
1. Периферийное устройство по специальной линии делает запрос контроллеру прямого доступа к памяти о том, что нужно передать данные в основную память.
|
||||
2. КПДП формирует сигнал Запрос ПДП, который отправляется в центральный процессор.
|
||||
3. ЦП видит запрос прямого доступа к памяти, отключается от системной шины и формирует сигнал Подтверждения ПДП
|
||||
4. КПДП выполняет пересылку данных.
|
||||
|
||||
Либо из центрального процессора, либо из периферийного устройства (в зависимости от конфигурации системы) КПДП получит адрес, с которого начнется запись в основную память (в случае переброски информации из периферийных устройств в основную память).
|
||||
|
||||
Передача данных из периферийного устройства в основную память:
|
||||
|
||||
1. КПДП запрашивает данные у периферийного устройства;
|
||||
2. Периферийное устройство передает информацию в регистр данных;
|
||||
3. КПДП выставляет адрес основной памяти;
|
||||
4. КПДП передает информацию из регистра данных в основную память;
|
||||
5. Уменьшается значение счетчика данных;
|
||||
6. Увеличивается адрес;
|
||||
7. Пока не закончился счетчик к пункту 1.
|
||||
|
||||
В одном устройстве может быть несколько DMA, если есть несколько шин.
|
||||
|
||||
DMA могут работать в разных режимах (режимы отличаются тем, насколько долго захватывают шину, то есть останавливают передачу информации между другими блоками системы):
|
||||
|
||||
- Взрывной режим (Burst mod) — контроллер захватывает шину пока не закончит свои дела;
|
||||
- Прозрачный режим — контроллер осуществляет пересылку информации только тогда, когда никто другой не занимает шину;
|
||||
- Делать по одно посылке за раз и отпускать шину на арбитраж.
|
||||
|
||||
## Конфигурации ПДП(DMA)
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Конфигурации ПДП.*
|
||||
|
||||
1. Подключен к шине как устройство;
|
||||
2. Выполняет роль модуля ввода-вывода для подключенного к нему набора периферийных устройств;
|
||||
3. КПДП подключается с одной стороны по выделенной шине к периферийным устройствам, а с другой к системной шине.
|
||||
|
||||
## Канальная система ввода-вывода
|
||||
|
||||
Канальная система ввода-вывода — это не просто прямой доступ к памяти, в ней есть специализированный процессор, который используется для того, чтобы связываться с периферийными устройствами.
|
||||
|
||||

|
||||
|
||||
*Рис. 13. Схема канальной системы ввода вывода.*
|
||||
|
||||
Канал(процессор) ввода-вывода — это контроллер прямого доступа к памяти, выполненный в виде специализированного процессора, которому можно давать сложные запросы и эти запросы будут обрабатываться программно.
|
||||
|
||||
Канал ввода-вывода имеет свою локальную память. Процессор ввода-вывода обращается за своими программами, которые осуществляют ввод-вывод, в основную память.
|
||||
|
||||
Каналы и процессоры ввода-вывода используются для подключения большого количества периферийных устройств. Благодаря им центральный процессор более эффективно тратит свое время.
|
||||
|
||||
## RAID
|
||||
|
||||
RAID (Redundant Array of Independent Disks) — избыточный массив независимых дисков.
|
||||
|
||||
Это объединение нескольких винчестеров, так чтобы повысить надежность хранения информации. Существуют разные способы объединения винчестеров в группу.
|
||||
|
||||

|
||||
|
||||
*Рис. 14. Классификация Паттерсона и Хеннесси.*
|
||||
|
||||
- RAID 0: не повышает надежность, объединяет диски с целью более быстрого доступа к ним.
|
||||
- RAID 1: информация клонируется на другие диски.
|
||||
- RAID 2: создается избыточность, для того чтобы можно было восстановить данные.
|
||||
- RAID 3: складываются по модулю 2 новое значение на одном из дисков и не изменившиеся значения на остальных трех дисках и записываются на избыточный диск. Получившееся значение называется битом четности (битом паритета).
|
||||
- RAID 4: складываются по модулю 2 бит четности, новое и старое значения элемента на одном из дисков и записываются на избыточный диск. Получается новый бит четности.
|
||||
|
||||

|
||||
|
||||
*Рис. 15. Расчет бита четности при обновлении данных в RAID 3 и RAID 4.*
|
||||
|
||||
- RAID 5: биты четности раскиданы по всем дискам, что позволяет добавлять новые значения параллельно.
|
||||
|
||||

|
||||
|
||||
*Рис. 16. Распределение битов четности в RAID 4 и RAID 5.*
|
||||
|
||||
- RAID 6: RAID 5, у которого вдвое увеличено количество избыточных контрольных дисков, то есть 2 диска, в которых хранятся паритеты, что повышает надежность.
|
||||
|
||||
## JTAG (Join Test Action Group)
|
||||
|
||||
JTAG — это четырехпроводной интерфейс, с помощью которого можно проверить правильно ли работает устройство. Его часто иcпользуют для отладки процессорной системы.
|
||||
|
||||
Граничное сканирование (Boundary Scan) — это способ тестирования микросхемы. Он заключается в том, что между каждой ножкой и ядром помещается ячейка памяти, эти ячейки соединяются как сдвиговый регистр. С помощью управляющих сигналов и сдвигового регистра мы можем считать информацию с ножек или выставить сигналы в ячейки памяти, что позволяет нам проверить работу всех выводов микросхемы, не подключаясь к ним. (Например, нам нужно узнать значение на определенной ножке. Мы сообщаем контроллеру JTAG, что нужно сохранить информацию с нее в ячейку памяти. Когда ячейка получит текущее состояние этого вывода, с помощью сдвигового регистра выдвигаем эту информацию на выход, где считываем ее).
|
||||
|
||||

|
||||
|
||||
*Рис. 17. Схема JTAG.*
|
||||
|
||||
TMS — управление.
|
||||
TDI и TDO — входной и выходной сигналы.
|
||||
TCK — сигнал тактирования.
|
||||
|
||||

|
||||
|
||||
*Рис. 18. Сканирующая цепочка.*
|
||||
|
||||

|
||||
|
||||
*Рис. 19. Ячейка памяти.*
|
||||
|
||||
Input Mux и Output Mux — мультиплексоры.
|
||||
Data_In и Data_Out — вход и выход данных ножки.
|
||||
Scan In и Scan Out — вход и выход сканирующей цепочки.
|
||||
Shift Register — один из триггеров сдвигового регистра (прикидываемся значениями с ножки).
|
||||
|
||||
Сигналами ShiftDR, Mode и др. управляют сигналы TMS и TCK. Они управляют не напрямую, а подключены к автомату состояний, который работает таким образом:
|
||||
|
||||

|
||||
|
||||
*Рис. 20. FSM (Finit State Machine) — конечный автомат (автомат состояний).*
|
||||
|
||||
где DR — Data Register, IR — Instruction Register
|
||||
|
||||
Автомат состояний используется для того, чтобы по-байтово битик за битиком загрузить в регистр нужную информацию.
|
||||
|
||||

|
||||
|
||||
*Рис. 21. Структура JTAG.*
|
||||
|
||||
TAP Controller устроен как автомат состояний. Он формирует сигналы для JTAG.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=XtoTG6qht3A&list=PL0def37HEo5KHPjwK7A5bd4RJGg4djPVf&index=21) на видеозапись лекции.
|
||||
|
||||
## Дополнительные материалы к лекции
|
230
Lectures/21. Microcontrollers.md
Normal file
230
Lectures/21. Microcontrollers.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# Лекция 21. Микроконтроллеры
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 21. Микроконтроллеры](#лекция-21-микроконтроллеры)
|
||||
- [Содержание](#содержание)
|
||||
- [Микроконтроллеры на примере PIC](#микроконтроллеры-на-примере-pic)
|
||||
- [PIC16F18313](#pic16f18313)
|
||||
- [Микроконтроллеры на примере ARM](#микроконтроллеры-на-примере-arm)
|
||||
- [Программа для микроконтроллера stm32f10x на языке C](#программа-для-микроконтроллера-stm32f10x-на-языке-c)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
- [Дополнительные материалы к лекции](#дополнительные-материалы-к-лекции)
|
||||
|
||||
> *Микроконтроллер* — это устройство, которое объединяет в себе процессор и ряд периферийных устройств и занимается управлением.
|
||||
|
||||
Электронные устройства можно условно разделить на несколько категорий:
|
||||
|
||||
1. Различные встраиваемые системы (которые куда-то встраиваются; например, встроенные в микроволновку, холодильник или телевизор)
|
||||
2. Системы общего назначения (персональные компьютеры, ноутбуки, мобильные телефоны)
|
||||
|
||||
В 70-х годах компанией Texas Instruments произведен первый патент на тему микроконтроллеров: "Организация микро-ЭВМ на одной микросхеме". Фактически контроллер является микро-ЭВМ (системой, которая объединяет процессор, периферийные модули, память команд, память данных).
|
||||
|
||||
Контроллеров выпускается на порядок больше, чем процессоров общего назначения.
|
||||
Микроконтроллеры используются везде (в игрушках, микроволновках, клавиатурах, мышках и т.д.).
|
||||
Микроконтроллеры есть в устройствах, которые производятся серийно, поэтому стараются сделать так, чтобы контроллер умел выполнять свои задачи и каждый его элемент стоил минимальную цену.
|
||||
|
||||
Контроллеры бывают различной разрядности.
|
||||
|
||||
- 8-битные. Они используются для решения простых задач (например, для сравнения каких-то параметров);
|
||||
- 16-битные. Они используются для более сложных задач, чем 8-битные, где нужна большая точность (например, для управления каким-то двигателем);
|
||||
- 32-битные контроллеры выполняют какие-либо вычисления: решают алгоритмы, проводят анализ сигналов.
|
||||
|
||||
Чтобы проверить подходит ли данный контроллер для устройства можно купить его и самому проверить, а можно купить отладочный комплект (starter kit или учебный комплект).
|
||||
|
||||
## Микроконтроллеры на примере PIC
|
||||
|
||||
Существуют различные семейства микроконтроллеров PIC. Они отличаются специализацией под определенные устройства и задачи.
|
||||
|
||||
Например в контроллерах семейства PIC16F19197 предусмотренно управление LCD-дисплеем.
|
||||
|
||||
Рассмотрим семейство PIC16F18446 (используется для подключения сенсоров, имеет низкое потребление энергии, маленький форм-фактор). Контроллеры данного семейства устанавливаются в маленькие устройства (может быть с батарейным питанием), которые получают значения с датчиков.
|
||||
|
||||
Помимо процессорного ядра на микросхеме находятся различные периферийные устройства. Например:
|
||||
|
||||
1. 12-битные аналого-цифровые преобразователи (для преобразования непрерывного во времени аналогового сигнала, в котором информация кодируется в виде уровня напряжения, в цифровой сигнал, который кодируется ноликами и единичками);
|
||||
2. Компараторы (сравнивают аналоговые сигналы друг с другом);
|
||||
3. Конфигурируемые логические ячейки (CLC или Configurable Logic Cell);
|
||||
4. Флеш память программ, основная память;
|
||||
5. EEPROM (электрически перезаписываемая программируемая память);
|
||||
6. PWM (Pulse-width modulation или широтно-импульсная модуляция);
|
||||
7. Waveform generator (генерирует сигналы);
|
||||
8. Цифро-аналоговый преобразователь (ЦАП или DAG) и другие.
|
||||
|
||||
Микроконтроллеры внутри рассматриваемого семейства отличаются размером памяти, количеством ножек, аналогово-цифровых преобразователей и максимальной аналогово-цифровой разрешающей способностью.
|
||||
|
||||
### PIC16F18313
|
||||
|
||||
Рассмотрим микроконтроллер PIC16F18313. В [документации](https://ww1.microchip.com/downloads/aemDocuments/documents/MCU08/ProductDocuments/DataSheets/40001799F.pdf) можно узнать, что это за контроллер и что он умеет.
|
||||
|
||||
Например:
|
||||
|
||||
- это RISC контроллер, поддерживающий 48 инструкций;
|
||||
- его входная тактовая частота — 32 MHz, минимальный тактовый цикл — 125 ns (величина критического пути);
|
||||
- Он имеет C-компилятор, систему прерываний, 16-уровневый стек для вызова подпрограмм, четыре 8-битых таймера, Watchdog Timer (когда таймер досчитывает до конца, он сбрасывает микроконтроллер, то есть перезапускает его. Он нужен для того, чтобы избежать зависаний во время работы) и т.д.
|
||||
|
||||
Данный микроконтроллер имеет 3 конфигурации: с 8-ю, 14-ю и 16-ю ножкам.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Микроконтроллер PIC16F18313 с 8-ю ножками.*
|
||||
|
||||
Для каждой конфигурации имеется табличка, в которой расписано, для чего может использоваться каждый конкретный вывод.
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Таблица подключения периферийных устройств для микроконтроллера PIC16F18313 с 8-ю ножками.*
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Схема микроконтроллера PIC16F18313.*
|
||||
|
||||
У данного контроллера мы видим CPU (центральный процессор), Timing Generator, который формирует сигналы тактирования.
|
||||
Микроконтроллер выполнен по Гарвардской архитектуре, то есть у него разделена память команд и память данных.
|
||||
Порты ввода-вывода, периферийные устройства и память данных подключены к CPU общей шиной данных.
|
||||
|
||||
Для подключения микроконтроллера PIC16F18313 нужно между пинами питания (VDD (высокий потенциал) и VSS (нулевой потенциал или земля)) поставить конденсатор C2, а на вход MCLR собрать схему (Note 1).
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Рекомендуемое минимальное подключение микроконтроллера PIC16F18313.*
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Тракт данных ядра (микроархитектура).*
|
||||
|
||||
Память программ, на которую указывает PC. Из нее выходит 14-битная инструкция, которая попадает в регистр инструкций. Данные из регистра используются для адресации в RAM и в устроистве управления (Instruction Decode and Control), которое формирует управляющие сигналы для всех блоков процессора.
|
||||
|
||||
Также мы видим аккумуляторную архитектуру, то есть один из входов АЛУ — это регистр аккумулятор (W Reg).
|
||||
|
||||
Управление системой происходит по обращению к конкретным адресам:
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Адреса регистров.*
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Форматы кодирования для микроконтроллера PIC16F18313.*
|
||||
|
||||
Пример программирование 32-битного контроллера PIC. Для этого, после подключения питания (Bypass capacitors), подаем тактирование (SG636PCE 40MHz oscillator), подключаем микроконтроллер к программатору (RJ11 ICD3 Jack).
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Схема подключения PIC32.*
|
||||
|
||||
Программатор одной стороной подключается к микроконтроллеру, а другой к компьютеру.
|
||||
|
||||

|
||||
|
||||
*Рис. 9. Программатор.*
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Пример кода, для отладки микроконтроллера.*
|
||||
|
||||
## Микроконтроллеры на примере ARM
|
||||
|
||||
Посмотрим 32-битный ARM микроконтроллер [STM32H723VE](https://www.st.com/en/microcontrollers-microprocessors/stm32h723ve.html).
|
||||
|
||||
Видим, что у данного контроллера ядро Cortex-M7, он работает на частоте 550MHz, имеет 1 MB флэш-памяти, 564 KB оперативной памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Характеристики микроконтроллера STM32H723VE.*
|
||||
|
||||
Ядро умеет работать с числами с плавающей запятой.
|
||||
|
||||
Контроллер может работать с графикой, имеет режим low power (низкого энергопотребления), аналоговую периферию, 4 DMA (прямой доступ к памяти), 24 таймера, термометр, генератор случайных чисел.
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Схема микроконтроллера STM32H723VE.*
|
||||
|
||||
В верхнем левом углу видим ядро, у которого отдельные кэш данных и кэш инструкции. Из него выходят наружу интерфейсы JTAG и ETM.
|
||||
|
||||
К ядру подключены 2 блока памяти данных, память инструкций.
|
||||
|
||||
У микроконтроллера много различных шин, работающих на разных скоростях, что необходимо для увеличения эффективности питания и работы. Например, периферия работает на более низких скоростях, а значит для нее нет необходимости делать лишние тактирования, которые происходили бы на высокоскоростной шине.
|
||||
|
||||
### Программа для микроконтроллера stm32f10x на языке C
|
||||
|
||||
Данная программа управляет миганием светодиода, подключенного к 5 разряду порта B:
|
||||
|
||||
```C
|
||||
#include "stm32f10x.h" //библиотека, созданная производителем микроконтроллеров
|
||||
|
||||
int main() {
|
||||
int i = 0;
|
||||
RCC->APB2ENR |= RCC_APB2ENR_IOPBEN // включили тактирование порта B
|
||||
GPIOB->CRL &= ~GPIO_CRL_CNFS; // сконфигурировали порт, как выходной
|
||||
GPIOB->CRL |= GPIO_CRL_MODES_0; // задали скорость переключения порта
|
||||
|
||||
while(1){
|
||||
i = 5000;
|
||||
while(i--); // уменьшает i до нуля
|
||||
GPIOB->BSRR = GPIO_BSRR_BS5; // установить 5 разряд порта B в единицу
|
||||
i = 5000;
|
||||
while(i--);
|
||||
GPIOB->BSRR = GPIO_BSRR_BR5; // установить 5 разряд порта B в ноль
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
*Рис. 13. Структурная организация ARM7.*
|
||||
|
||||
ARM7 — это классический представитель ядер для микроконтроллеров.
|
||||
|
||||
Он включает в себя:
|
||||
|
||||
- Конвейер команд, подключенный к декодеру команд, который управляет всеми блоками тракта данных процессора;
|
||||
- 32-битное АЛУ, которое может записывать в регистровый файл либо выдавать свое значение на регистр адреса, чтобы обращаться к основной памяти;
|
||||
- Регистровый файл, один из регистров которого счетчик команд (PC), второй подключен к АЛУ.
|
||||
|
||||
У ARM7 старая архитектура. Она развивалась и появились новые ядра. Например, ARM9.
|
||||
|
||||
В него входят:
|
||||
|
||||
- Регистрового файла;
|
||||
- Множество мультиплексоров, которые выбирают откуда и что пойдет на АЛУ;
|
||||
- АЛУ;
|
||||
- Shifter.
|
||||
|
||||

|
||||
|
||||
*Рис. 14. Структурная организация ARM9.*
|
||||
|
||||
Cortex-A9 — более современное, чем ARM7 и ARM9, ядро. Он еще может встречаться в контроллерах.
|
||||
|
||||
У Cortex-A9 есть:
|
||||
|
||||
- Кэш команд;
|
||||
- Блок предсказания переходов:
|
||||
- Глобальный буфер истории (Global history register);
|
||||
- Кэш конечных адресов перехода (Branch target buffer). В нем кэшируется адрес, куда будет произведен;
|
||||
- Стек адресов возврата;
|
||||
- Блок переименования регистров(переименование нужно для суперскалярности, устранения конфликтов read-after-write, write-after-write);
|
||||
- Окно диспетчеризации (очередь команд общая и она диспетчеризует куда пойдет следующая инструкция);
|
||||
- Исполнительные устройства (АЛУ с умножением, АЛУ, FPU — Floating Point Unit и другие).
|
||||
|
||||

|
||||
|
||||
*Рис. 15. Схема работы Cortex-A9.*
|
||||
|
||||
Современные реализации микроконтроллеров могут включать в себя несколько ядер.
|
||||
|
||||

|
||||
*Рис. 16. Cortex-A7 и Cortex-A15.*
|
||||
|
||||
При использовании двух ядер, одно может быть мене производительным чем другое, но при этом потреблять меньше энергии и использоваться в сценариях, где не нужна высокая эффективность. Переключения между ядрами позволяет балансировать между затратами на энергию и производительностью.
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=Z0ohQdYn2VU&list=PL0def37HEo5KHPjwK7A5bd4RJGg4djPVf&index=21) на видеозапись лекции.
|
||||
|
||||
## Дополнительные материалы к лекции
|
||||
|
||||
1. [Ссылка](https://www.microchip.com/en-us/products/microcontrollers-and-microprocessors/8-bit-mcus/pic-mcus) на сайт производителя микропроцессоров PIC.
|
||||
2. [Ссылка](https://onedrive.live.com/?authkey=%21AIXUSz0MyutL6hs&cid=1FF28DEC684C2C56&id=1FF28DEC684C2C56%2181801&parId=1FF28DEC684C2C56%2181696&o=OneUp) на статью, в которой описана сборка однотактного процессора с архитектурой PIC.
|
178
Lectures/22. General purpose systems.md
Normal file
178
Lectures/22. General purpose systems.md
Normal file
@@ -0,0 +1,178 @@
|
||||
# Лекция 22. Системы общего назначения
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 22. Системы общего назначения](#лекция-22-системы-общего-назначения)
|
||||
- [Содержание](#содержание)
|
||||
- [Микропроцессоры](#микропроцессоры)
|
||||
- [История x86](#история-x86)
|
||||
- [Тик-так](#тик-так)
|
||||
- [Coffee lake](#coffee-lake)
|
||||
- [Front-end](#front-end)
|
||||
- [Execution Engine](#execution-engine)
|
||||
- [Gen9.5](#gen95)
|
||||
- [AMD Zen](#amd-zen)
|
||||
- [Из чего состоит компьютер?](#из-чего-состоит-компьютер)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
|
||||
## Микропроцессоры
|
||||
|
||||
Для начала повторим классификацию микропроцессоров.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. Классификация микропроцессоров.*
|
||||
|
||||
**Микропроцессоры общего назначения** – нужны для решения любых задач, они не предназначен для специализированных задач. Для них мы используем **специализированные микропроцессоры**.
|
||||
|
||||
**Специализированные микропроцессоры** – альтернатива, которую мы можем разделить на **микроконтроллеры** и **процессоры цифровой обработки сигналов**. Про микроконтроллеры мы подробнее поговорили на прошлой лекции.
|
||||
|
||||
**Процессоры цифровой обработки сигналов** – фактически это те же **микроконтроллеры**, но они больше ориентированы на цифровую обработку сигналов.
|
||||
|
||||
В этой лекции мы рассмотрим процессоры общего назначения.
|
||||
|
||||
## История x86
|
||||
|
||||
Процессоры архитектуры **x86** имеют архитектуру с полным набором команд, то есть поддерживают большое количество инструкций с разной шириной.
|
||||
|
||||
Впервые архитектура **x86** была представлена компанией Intel в 1978 году (Intel **8086**). Следующие версии **8086** стали совершенствовать первую версию добавлением новых инструкций, таймеров, контроллеров, защищенных режимов и т.д. Полный список представлен в таблице 1.
|
||||
|
||||
| Версия | Что было добавлено | Год выпуска |
|
||||
|:------------|:---------------------------------------------------------------:|:-----------:|
|
||||
| Intel 8086 | 16-битный, 98 инструкций, 7 режимов адресации | 1978 |
|
||||
| Intel 80186 | Новые инструкции, КПДП, таймеры, контроллер прерывания | 1982 |
|
||||
| Intel 80286 | Защищенный режим, виртуальная память | 1982 |
|
||||
| Intel 80386 | 32-битный, страничная организация, до 4 Гб памяти | 1985 |
|
||||
| Intel 80486 | Сопроцессор, 150 инструкций | 1989 |
|
||||
| P6 | Суперскалярный CISC, RISC-ядро, предсказание условных переходов | 1995 |
|
||||
| MMX | **M**ulti**m**edia E**x**tensions (мультимедийные расширения) | 1997 |
|
||||
|
||||
*Таблица 1. Развитие процессора Intel 8086.*
|
||||
|
||||
## Тик-так
|
||||
|
||||
Когда Intel делают свои процессоры они используют подход **"Тик-так"**. Суть его заключается в том, что они в одном году разрабатывают новую архитектуру (**тик**), а в следующем осваивают новый тех. процесс (**так**). На рисунке 2 можно увидеть как работал **"Тик-так"** до 2015 года, сейчас это работает немного "криво", но общая идея понятна.
|
||||
|
||||

|
||||
|
||||
*Рис. 2. Подход Тик-так.*
|
||||
|
||||
## Coffee lake
|
||||
|
||||
Рассмотрим микроархитектуру процессора **Coffee Lake**, выпущенного в 2017-ом году. Она состоит из трех основных блоков:
|
||||
|
||||
- **Memory Subsystem** (подсистема памяти);
|
||||
- **Execution Engine** (RISC-ядра);
|
||||
- **Front-end** (CISC-оболочка поверх **Execution Engine**).
|
||||
|
||||

|
||||
|
||||
*Рис. 3. Микроархитектура Coffee Lake.*
|
||||
|
||||
Разберём каждый блок подробнее:
|
||||
|
||||
### Front-end
|
||||
|
||||
Из **кеш-памяти** за один такт считывается сразу 16 байт CISC-инструкций, которые подаются в **Буфер предварительного декодирования** (**Instruction Fetch & PreDecode**). **x86**-инструкции сложны, имеют переменную длину, несогласованное кодирование и могут содержать несколько операций. Буфер предварительного декодирования выполняет разметку границ инструкций. Это довольно сложная задача, так как длина каждой инструкции может варьироваться от одного байта до пятнадцати. Кроме того, для определения длины может потребоваться просмотр нескольких первых её байт. Помимо разметки границ, декодируются префиксы инструкции, которые затем проверяются на различные свойства, например ветвления[\[1\]](https://en.wikichip.org/wiki/intel/microarchitectures/skylake#Front-end).
|
||||
|
||||
Из блока **Буфера предварительного кодирования** выходят до 6 макро-операций, которые затем подаются в блок **очереди инструкций**, где (в некоторых случаях) благодаря **Macro-Fusion** две последовательно идущие инструкции могут быть преобразованы в одну.
|
||||
|
||||

|
||||
|
||||
*Рис. 4. Пример объединения двух инструкций в блоке **Macro-Fusion**[\[2\]](https://en.wikichip.org/wiki/intel/microarchitectures/skylake#Instruction_Queue_.26_MOP-Fusion).*
|
||||
|
||||
За такт может произойти только одно подобное объединение. Иными словами, даже если в очереди окажется две пары подходящих для объединения инструкций, объединена будет только первая пара (кроме того, есть и другие ограничения по объединению)[\[3\]](https://en.wikichip.org/wiki/macro-operation_fusion#Mechanism).
|
||||
|
||||
Почему этап **Macro-Fusion** не может быть реализован на этапе компиляции программы? Дело в том, что в результате этого преобразования, результирующая макро-операция уже не является какой-то стандартной x86-инструкцией. Вместо этого, она становится какой-то специальной инструкцией, которая в дальнейшем может быть декодирована и исполнена только данной микроархитектурой процессора.
|
||||
|
||||
В наборе инструкций x86 нет операции условного перехода в том виде, в котором они представлены в ISA RISC-V. Вместо этого, условный переход делится на две инструкции:
|
||||
|
||||
- инструкция вычисления результата условия
|
||||
- инструкция прыжка в зависимости от результата условия
|
||||
|
||||
Таким образом, каждый такой переход накладывает на процессор штраф в одну дополнительную инструкцию. При создании новых процессоров уже невозможно избавиться от этого штрафа через изменение существующей ISA x86 (из-за проблем с обратной совместимостью программ), именно поэтому и был создан данный блок[\4\]](https://arxiv.org/pdf/1607.02318.pdf).
|
||||
|
||||
Из **Instruction Queue** выходит 5 макро-инструкций (с учётом того, что две из шести инструкций могли быть объединены), и попадают в **5-Way Decode** (**пятисекционный дешифратор**).
|
||||
|
||||
**Пяти секционный дешифратор** преобразует макро-операции в микро-операции (которые похожи на RISC-инструкции). Простые макро-операции попадают в **Simple Decoder** и преобразуются в одну микро-операцию. Более сложные попадают в **Complex Decoder**. Самые сложные макро-операции полагаются на память микропрограмм **MicroCode Sequencer** (где написана целая микропрограмма для исполнения конкретной макро-операции). Помимо прочего здесь подключен **Stack Engine** — аппаратный блок, позволяющий вычислять обновленное значение указателя на стек (без исполнения соответствующей микро-операции).
|
||||
|
||||
**Предсказатель результата ветвлений** (**Branch Predictor**) говорит о том какой адрес необходимо использовать для получения новых инструкций еще до вычисления результата ветвления.
|
||||
|
||||
**Буфер декодированного потока инструкций** (**Decoded Stream Buffer**) содержит декодированные ранее операции. В случае, если будут получены макро-операции, которые уже были недавно декодированы, данный буфер сможет сразу же выдать готовые микро-инструкции.
|
||||
|
||||
В блоке **MUX** мы имеем набор инструкций, которые уже нужно выполнить. От туда они попадают в **Allocation Queue**, где мы также имеем **Micro-Fusion** для дополнительной доработки микро инструкций. **Loop Stream Detector** необходим для запоминания последних 18 инструкций и определяет есть ли цикл. Из этого блока мы переходим к **Execution Engine**.
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Front-end Coffee Lake.*
|
||||
|
||||
### Execution Engine
|
||||
|
||||
**ReOrder Buffer** получает инструкции и переименовывает используемые ими регистры, чтобы избежать конфликтов (чтение после записи, попытка записи в один регистр и т.д.). Переименовывание означает использование теневых регистров из **RAT - Register Alias Table** (дополнительных регистров), они необходимы для того, чтобы не нарушать порядок записи в одну ячейку и записать результат в теневой регистр. Из блока **ReOrder Buffer** выходят микро инструкции с известными адресами куда они будут сохранены, переименованными регистрами и т.д. Они попадают в **Scheduler Unified Reservation Station**
|
||||
|
||||
В **Scheduler Unified Reservation Station (планировщик)** происходит диспетчеризация, то есть микро инструкции раздаются на различные порты. **Планировщик** имеет два файла регистров для целых чисел и векторов. Именно в этих файлах регистров хранятся выходные данные операндов. На выходе каждого порта стоят функциональные блоки (**EUs - Execution Units**). Планировщик удерживает микро-операции, пока они ожидают выполнения. Микро-операция может ожидать операнда, который еще не прибыл (например, выбран из памяти или в настоящее время вычисляется из других микро-операций) или потому, что необходимый ему исполнительный блок занят. Как только микро-операция готова, она отправляется через назначенный порт. Планировщик будет отправлять самую старую готовую инструкцию для выполнения на каждом из восьми портов в каждом цикле. Каждый из этих портов выполняет свои задачи - целочисленное ALU, целочисленное деление, векторные операции и т.п. Некоторые из этих блоков подключены к подсистеме памяти (**Memory Subsystem**).
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Execution Engine Coffee Lake.*
|
||||
|
||||
**Memory Subsystem** – подсистема памяти, отвечающая за загрузку, запросы к сохранению и упорядочивание. Данные попадают в **Load Buffer** и **Store Buffer**, подключенные к кешу первого уровня **L1 Data Cache**, который в свою очередь передаёт всё в кеш второго уровня. В каждом цикле можно выполнить одну операцию, т. е. L1 может либо получать данные от L2, либо отправлять данные в буферы загрузки/сохранения каждый цикл, но не то и другое. **L2 Cache** уже является общим для команд и для данных.
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Memory Subsystem Coffee Lake.*
|
||||
|
||||
Выше мы рассмотрели одно ядро. **Coffee Lake** может иметь 4, 6 и 8 ядер (на рисунке 8 представлен 4-ядерный процессор). Подсистемы памяти каждого ядра объединяются в **кольцевую шину**. **Кольцевая шина** передаёт информацию по кругу, благодаря чему устраняются конфликты, допустим когда несколько устройств хотят завладеть шиной. В правой части находится **System Agent**. Он связан с взаимодействием с памятью, дисплеем и другими внешними устройствами.
|
||||
|
||||

|
||||
|
||||
*Рис. 8. четырёхъядерный процессор Coffee Lake.*
|
||||
|
||||
Метод **кольцевой шины** имеет и минусы – если её расширять, то её пропускная способность падает.
|
||||
|
||||
## Gen9.5
|
||||
|
||||
**Gen9.5** – графическое ядро. Оно состоит из
|
||||
|
||||
- **Command Streamer** – устройство, которое управляет потоком исполнения.
|
||||
- **EU (Execution Unit)** – исполнительные устройства, производящие вычисления.
|
||||
|
||||

|
||||
|
||||
*Рис. 9. Графическое ядро Gen9.5.*
|
||||
|
||||
## AMD Zen
|
||||
|
||||
Для сравнения рассмотрим микро архитектуру **AMD Zen**. Многие блоки совпадают с **Coffee Lake**, поэтому акцентируем внимание на отличиях: в данной реализации инструкции сортируются в зависимости от того целочисленные они (Integer) или с плавающей запятой (FP/SIMD). Этот пример используется в ознакомительных целях - показать, что есть и другие микро архитектуры.
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Микроархитектура AMD Zen.*
|
||||
|
||||
## Из чего состоит компьютер?
|
||||
|
||||
Выйдем на уровень системы. Ранее мы рассматривали только Центральный Процессор (ЦП)**. Сейчас же мы разберём из чего в целом состоит компьютер:
|
||||
|
||||
- **Центральный процессор**
|
||||
- **Генератор тактовых импульсов**
|
||||
|
||||
- **Чипсет** – набор микросхем, управляющих общением процессора, памяти и периферийных устройств. Обычно состоит из двух микросхем:
|
||||
- **Северный мост** — это контроллер-концентратор памяти, который взаимодействует с памятью и высокоскоростными устройствами `PCI-E`. Чтобы ускорить общение с высокоскоростной шиной в современных процессорах северных мост стали встраивать в **ЦП**.
|
||||
- **Южный мост** — контроллер-концентратор ввода-вывода, который связан с медленными устройствами (BIOS, PCI, SATA и т.п.).
|
||||
|
||||
- **BIOS** – базовая система ввода-вывода. С загрузки **BIOS** начинается включение компьютера: **BIOS** копирует свою программу в основную память, после чего передает управление процессору, чтобы тот проверил: какое оборудование подключено, как его необходимо сконфигурировать и в рабочем ли состоянии оно находится (т.е. сканирует и конфигурирует систему).
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Материнская плата в схематичном варианте.*
|
||||
|
||||
На рис. 12 представлена иллюстрация расположения **северного** и **южного моста** на материнской плате.
|
||||
Обратите внимание на то, что **северный мост** находится ближе к процессору, а **южный** к периферии, USB и т.п.
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Материнская плата.*
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=w7CcAgTtL6k&list=PL0def37HEo5KHPjwK7A5bd4RJGg4djPVf&index=22) на видеозапись лекции
|
229
Lectures/23. Parallel computing systems.md
Normal file
229
Lectures/23. Parallel computing systems.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# Лекция 23. Параллельные вычислительные системы
|
||||
|
||||
## Содержание
|
||||
|
||||
- [Лекция 23. Параллельные вычислительные системы](#лекция-23-параллельные-вычислительные-системы)
|
||||
- [Содержание](#содержание)
|
||||
- [Классификация](#классификация)
|
||||
- [По области применения](#по-области-применения)
|
||||
- [По особенностям назначения](#по-особенностям-назначения)
|
||||
- [Классификация Флинна](#классификация-флинна)
|
||||
- [Альтернативная классификация](#альтернативная-классификация)
|
||||
- [Классификация по памяти](#классификация-по-памяти)
|
||||
- [Обобщенная структура параллельно вычислительной системы](#обобщенная-структура-параллельно-вычислительной-системы)
|
||||
- [Матричные вычислительные системы](#матричные-вычислительные-системы)
|
||||
- [Кластерные вычислительные системы (ВС)](#кластерные-вычислительные-системы-вс)
|
||||
- [Топология малых кластеров](#топология-малых-кластеров)
|
||||
- [Реконфигурируемые вычислительные системы](#реконфигурируемые-вычислительные-системы)
|
||||
- [Систолические вычислительные системы](#систолические-вычислительные-системы)
|
||||
- [Системы, управляемые потоками данных](#системы-управляемые-потоками-данных)
|
||||
- [Основные материалы лекции](#основные-материалы-лекции)
|
||||
|
||||
|
||||
**Параллельные вычислительные системы (ПВС)** нужны для повышения производительности, чтобы выполнять вычисления как можно быстрее за счёт того, что каждое ядро решает свои задачи. Однако параллелизм бывает разный, об этом и рассказывается в рамках этой лекции.
|
||||
|
||||
## Классификация
|
||||
|
||||
### По области применения
|
||||
|
||||
- **Научные вычисления (grand challenges)** – к примерам таких вычислений можно отнести обработку больших данных, моделирование взрыва ядерных бомб, вычисление сложности алгоритмов и т.п.
|
||||
|
||||
- **Глобальные корпоративные вычисления**, которые делятся на две подкатегории
|
||||
- Обработка баз данных корпораций
|
||||
- Многопоточная обработка запросов
|
||||
|
||||
### По особенностям назначения
|
||||
|
||||
- **Системы высокой надежности** – к ним относятся различные системы (например банковские), для которых надёжность является один из главных факторов. Такие системы являются избыточными, так как им необходима горячая замена различных ресурсов (элементов памяти, процессоров и т.п.), в случае если что-то выйдет из строя.
|
||||
|
||||
- **Системы высокопроизводительных вычислений** – название говорит само за себя, это процессоры нацеленные на высокопроизводительные вычисления.
|
||||
|
||||
- **Многопоточные системы** – к ним относятся различные web-сервера, которым нужно одновременно отвечать на множество запросов, когда люди заходят на сайт.
|
||||
|
||||
## Классификация Флинна
|
||||
|
||||
**Классификация Флинна** – общая классификация архитектур ЭВМ по признакам наличия параллелизма в потоках команд и данных. Была предложена Майклом Флинном в 1966 году и расширена в 1972 году.
|
||||
Её идея заключалась в том, чтобы представить машину как обработчик потока команд и потока данных, и в зависимости от того какие потоки команд и данных обрабатывает машина, классифицировать её одним из 4 способов:
|
||||
|
||||
- **SISD (Single Instruction Single Data)** (на одиночный поток команд приходится одиночный поток данных) – это традиционный процессор (к примеру однотактный). Каждой команде соответствует своя порция данных, она обрабатывается процессором, который выдаёт результат.
|
||||
|
||||

|
||||
|
||||
*Рис. 1. SISD (Single Instruction Single Data).*
|
||||
|
||||
- **SIMD (Single Instruction Multiple Data)** (на одиночный поток команд приходится множественный поток данных) – он состоит из памяти программ, которая выдаёт одну инструкцию и эта инструкция является указанием всем вычислителям в системе, чтобы они каждый работали над своей порцией данных.
|
||||
|
||||

|
||||
|
||||
*Рис. 2. SIMD (Single Instruction Multiple Data).*
|
||||
|
||||
- **MISD (Multiple Instruction Single Data)** (на множественный поток инструкций единственные данные) – это конвейер, то есть одна порция данных проходит через конвейер (формально это одна команда, которая разбита на стадии).
|
||||
|
||||

|
||||
|
||||
*Рис. 3. MISD (Multiple Instruction Single Data).*
|
||||
|
||||
- **MIMD (Multiple Instruction Multiple Data)** (множественный поток инструкций для различных данных) – при таком подходе можно одновременно генерировать множество команд для различных данных и получать различные результаты на выходе.
|
||||
|
||||

|
||||
|
||||
*Рис. 4. MIMD (Multiple Instruction Multiple Data).*
|
||||
|
||||
## Альтернативная классификация
|
||||
|
||||
Эта классификация основывается на **классификации Флинна** и расширяет её.
|
||||
|
||||
- **Системы с конвейерной и векторной обработкой** – похоже на работу **SIMD**, но использующие векторные системы.
|
||||
|
||||
- **SIMD-системы** – такие системы с процессорными элементы, которыми управляет один процессор.
|
||||
|
||||
- **MIMD-системы**
|
||||
- Сильносвязнные (с общей памятью) – если программа лежит в общей памяти.
|
||||
- Слабосвязанные (с локальной памятью) – архитектура, в которой передача информации между отдельными элементами этой системы происходит за счёт передачи явных сообщений.
|
||||
|
||||
- **Multiple SIMD** – объединений SIMD процессоров.
|
||||
|
||||
## Классификация по памяти
|
||||
|
||||
- **Symmetric Multiprocessing (SMP)** – системы с однотипными процессорами и общей памятью. Их преимущества: легкое и быстрое общение между процессорами, но они плохо поддаются масштабированию, что является частой задачей.
|
||||
На рисунке 5 показан классический вариант реализации **SMP**
|
||||
|
||||

|
||||
|
||||
*Рис. 5. Symmetric Multiprocessing (SMP).*
|
||||
|
||||
**SMP** может быть реализован по другому - один из вариантов это перекрёстное подключение, когда каждый из элементов может обращаться к своим модулям, но такая реализация достаточно сложна и требует больших аппаратных затрат.
|
||||
|
||||

|
||||
|
||||
*Рис. 6. Symmetric Multiprocessing (SMP) с перекрёстным подключением.*
|
||||
|
||||
Также есть вариант с коммутаторами, благодаря которым происходит маршрутизация запросов. Это попытка сделать вариант SMP с перекрёстным подключением, но чуть более в упрощённом варианте.
|
||||
|
||||

|
||||
|
||||
*Рис. 7. Symmetric Multiprocessing (SMP) с коммутаторами.*
|
||||
|
||||
- **Message Passing Architecture (MPA)** – архитектура с передачей сообщений через высокоскоростную коммутационную среду. Она сложнее организуется, но она проще масштабируется, а также является гетерогенной, то есть может использовать разные процессоры, в том числе с разной архитектурой.
|
||||
|
||||

|
||||
|
||||
*Рис. 8. Message Passing Architecture (MPA).*
|
||||
|
||||
- **Non-Uniform Memory Access (NUMA)** – архитектура, которая в качестве реализации выглядит как система с общей памятью, то есть у всех процессоров есть общая память и они могут писать в любой адрес, но на самом деле она такой не является - у каждого устройства своя локальная память, но за счёт общих коммутаторов, для отдельного процессора это выглядит как единая память.
|
||||
|
||||

|
||||
|
||||
*Рис. 9. Non-Uniform Memory Access (NUMA).*
|
||||
|
||||
### Обобщенная структура параллельно вычислительной системы
|
||||
|
||||
Обобщенно структуру **параллельно вычислительной системы (ПВС)** можно изобразить следующим образом: есть высокоскоростная коммутационная среда, которая подключает различные вычислительные узлы. Каждый вычислительный узел это набор процессорных элементов, которые подключены к коммутатору, соединяющий их с памятью.
|
||||
|
||||

|
||||
|
||||
*Рис. 10. Обобщенная структура ПВС.*
|
||||
|
||||
## Матричные вычислительные системы
|
||||
|
||||
Матричные вычислительные системы относятся к **SIMD** системам. Они состоят из набора процессоров, имеющих свою локальную память и коммутационную среду с помощью которой процессоры общаются друг с другом. Также есть высокопроизводительный управляющий процессор, он считывает программу и выставляет задачу процессорам (в том числе и их активацию). На рисунке 11 представлена такая реализация.
|
||||
|
||||

|
||||
|
||||
*Рис. 11. Первый способ реализации матричной вычислительной системы.*
|
||||
|
||||
На рисунке 12 представлен другой способ реализации, где процессоры не на прямую подключены к своему банку памяти, а через коммутационную среду. То есть процессоры могут обращаться к другим банкам памяти, это увеличивает гибкость матричного вычислителя, но также значительно его усложняет.
|
||||
|
||||

|
||||
|
||||
*Рис. 12. Второй способ реализации матричной вычислительной системы.*
|
||||
|
||||
## Кластерные вычислительные системы (ВС)
|
||||
|
||||
**Кластеры** – объединений гетерогенных структур для решения общей задачи под единым программным обеспечением.
|
||||
|
||||
Преимущества кластерных вычислительных систем:
|
||||
|
||||
- **абсолютная масштабируемость** – можно изначально создать огромный кластер.
|
||||
- **наращиваемая масштабируемость** – кластер можно продолжать масштабировать.
|
||||
- **высокий коэффициент готовности** – за счёт того, что уже есть большое количество машин.
|
||||
- **соотношение цена/производительность** – кластеры значительно выигрывают в цене по сравнению с другими параллельными вычислительными системами.
|
||||
|
||||
На рисунке 13 представлены две реализации **кластерных вычислительных систем**. Слева представлена реализация с общим дисковым массивом, справа же системы связаны только высокоскоростной магистралью.
|
||||
|
||||

|
||||
|
||||
*Рис. 13. Кластерные вычислительные системы.*
|
||||
|
||||
## Топология малых кластеров
|
||||
|
||||
На рисунке 14 представлены разные реализации малых кластеров. Самый простой – под номером 4, у каждого узла есть свой дисковый массив. Остальные варианты используются для обеспечения надёжности:
|
||||
|
||||
- Вариант под номером 1 – перекрёстный. За счёт такого перекрёстного подключения ресурсы дублируются, и есть возможность заменить один из узлов в случае, если он выйдет из строя.
|
||||
- Вариант под номером 2 – N+M. Благодаря коммутатору каждый узел кластера имеет возможность получить доступ к любому дисковому массиву.
|
||||
- Вариант под номером 3 – N+1. Здесь есть один узел, который создаёт избыточность и страхует если какой-то из узлов выйдет из строя.
|
||||
|
||||

|
||||
|
||||
*Рис. 14. Кластерные вычислительные системы.*
|
||||
|
||||
## Реконфигурируемые вычислительные системы
|
||||
|
||||
**Реконфигурируемые вычислительные системы (РВС)** — это системы, имеющие возможность менять свою модель вычислений, иначе говоря, позволяющие вносить существенные изменения в свою аппаратную часть. Основное отличие — это наличие **программируемой логической интегральной схемы (ПЛИС)** и возможность по мере необходимости реконфигурировать **ПЛИС** компьютером. Благодаря **ПЛИС** данные обрабатываются потоково.
|
||||
|
||||

|
||||
|
||||
*Рис. 15. Реконфигурируемые вычислительные системы.*
|
||||
|
||||
## Систолические вычислительные системы
|
||||
|
||||
Систолические вычислительные системы – системы класса **SIMD**, основным принципом которых является то, что все данные регулярно и ритмически проходящие через массив, используются многократно. Она состоит из цепочки процессорных элементов, которые поэтапно взаимодействуют между собой. Важное отличие, что здесь не происходит обращение к памяти.
|
||||
|
||||

|
||||
|
||||
*Рис. 16. Систолические вычислительные системы.*
|
||||
|
||||
## Системы, управляемые потоками данных
|
||||
|
||||
Мы привыкли, что обычно машина управляется потоком команд — пришла команда и она выполняется. Но сейчас мы рассмотрим другой подход.
|
||||
|
||||
Идея **систем, управляемых потоком данных** заключается в том, что не новая инструкция порождает новые вычисления, а готовые данные порождают новые вычисления.
|
||||
|
||||
Чтобы разобраться, как работает данная система, рассмотрим элементы описания этой машины, представленной на рисунке 17.
|
||||
|
||||
Принцип работы будет описан в виде направленного графа, где по стрелочкам идут данные, в кружочках обозначаются операции:
|
||||
|
||||
- а – бинарная операция
|
||||
- б – унарная операция
|
||||
- в – разветвление
|
||||
- г – объединение
|
||||
- д – мультиплексор
|
||||
- е – проверка на True
|
||||
- ж – проверка на False
|
||||
- з – арбитр (кто первый придёт – направо, второй – налево)
|
||||
|
||||

|
||||
|
||||
*Рис. 17. Элементы системы, управляемые потоками данных.*
|
||||
|
||||
Рассмотрим работу **систем, управляемых потоком данных** на примере решения корней квадратного уравнения.
|
||||
|
||||

|
||||
|
||||
*Рис. 18. Решение корней квадратного уравнения.*
|
||||
|
||||
Также мы можем реализовать цикл, пример на рисунке 19.
|
||||
|
||||

|
||||
|
||||
*Рис. 19. Цикл.*
|
||||
|
||||
Пример реализации такой системы представлен на рисунке 20. Она состоит из группы коммутаторов, блоков памяти и процессорных элементов. Одно прохождение по этому кругов данных соответствует одной линии, которая была представлена на рисунке 18.
|
||||
|
||||

|
||||
|
||||
*Рис. 20. Пример реализации системы, управляемой потоками данных.*
|
||||
|
||||
## Основные материалы лекции
|
||||
|
||||
1. [Ссылка](https://www.youtube.com/watch?v=ew5WILrjK5A&list=PL0def37HEo5KHPjwK7A5bd4RJGg4djPVf&index=23) на видеозапись лекции
|
Reference in New Issue
Block a user