Гарвардская архитектура: Разделяй и властвуй
Представь, что ты повар на кухне. У тебя есть книга с рецептами — инструкции, что нужно делать, — и холодильник с продуктами — данные, с которыми ты работаешь. Будет очень неудобно и странно хранить бумажную книгу прямо внутри холодильника рядом с колбасой.
В архитектуре компьютеров действует тот же принцип. В так называемой «Гарвардской архитектуре» память для программ (ПЗУ, или ROM) и память для данных (ОЗУ, или RAM) — это два совершенно разных устройства, подключённых к процессору по разным шинам.
ПЗУ хранит сам код программы — те самые команды «сложить», «сохранить», «перейти». Процессор только читает оттуда инструкции и никогда не перезаписывает их во время работы. А вот ОЗУ — это черновик: туда процессор постоянно что-то пишет, стирает и сохраняет промежуточные результаты — координаты игрока, счёт, здоровье.
Разделение памятей даёт главный выигрыш — параллелизм. Пока дешифратор разбирает текущую команду, счётчик команд уже подтягивает следующую из ROM. Именно поэтому Гарвардская архитектура быстрее — и именно её ты соберёшь на уровне 1.18.
Почему одна шина — узкое место
Альтернатива — архитектура фон Неймана: там инструкции и данные лежат в одной памяти и ходят по одной шине. Это проще и гибче: код можно менять во время работы, память не простаивает. Но есть цена: шина в каждый момент времени передаёт что-то одно — либо команду, либо данные.
Это явление называют «узким местом фон Неймана» (Von Neumann bottleneck). Процессор вынужден ждать, пока шина освободится, и не может одновременно читать следующую команду и записывать результат. В Гарвардской архитектуре дорог две — и таких пробок нет.
Как устроен компьютер Ершова
Финальный компьютер на уровне 1.18 — классическая Гарвардская схема. Данные текут слева направо по цепочке: ProgramCounter → ROM → Splitter → Decoder → Register8 и ALU8 → RAM.
Счётчик команд выставляет адрес на ROM, ROM отдаёт байт команды, Splitter делит его пополам: старшие биты 4–7 — это opcode (что делать), младшие биты 0–3 — операнд (с чем делать). Дешифратор превращает opcode в управляющие сигналы, а регистры и АЛУ выполняют работу с данными. Сами данные живут в RAM — отдельной памяти на отдельной шине.
Восьмибитные регистры мы собрали в статье про первый байт, а устройство счётчика команд разберём в следующей статье. Сейчас важно понять связку: команды и данные не мешают друг другу.
Путь данных: как команда LDA доходит до аккумулятора
Посмотрим на команду LDA — «загрузить в аккумулятор». LDA загружает непосредственное значение: операнд команды приходит из ROM, проходит через мультиплексор (в этот момент он выбирает не шину данных, а операнд команды) и попадает прямо в регистр-аккумулятор. Запись в аккумулятор происходит по следующему фронту такта — сначала данные успевают устояться на шине.
Важно: шина данных, по которой едет содержимое RAM, — это отдельная дорога от шины команд, по которой из ROM приходят инструкции и их операнды. Поэтому за один такт можно одновременно дочитать команду и доставить данные — именно это и делает компьютер Ершова быстрым.
Гарвард против фон Неймана
Сведём главные отличия в таблицу.
| Свойство | Гарвардская архитектура | Архитектура фон Неймана |
|---|---|---|
| Память | Отдельные ROM и RAM | Одна общая память |
| Шины | Две: для команд и для данных | Одна общая шина |
| Чтение команды + запись данных | Одновременно, параллельно | Только по очереди |
| Скорость | Быстрее для простых задач | Проще, но медленнее |
| Изменение кода во время работы | Нельзя: ROM только для чтения | Можно |
| В игре | Уровень 1.18 — компьютер Ершова | Теоретическая альтернатива |
Один такт на числах
Разберём конкретный такт. Пусть счётчик команд читает из ROM[3] следующую команду, а АЛУ в это же время записывает результат вычисления в RAM[12].
Шаг 1. Счётчик команд выставляет на шину адреса значение 3 — ROM готовит к выдаче байт команды.
Шаг 2. Одновременно по шине данных в RAM[12] записывается результат АЛУ: адрес 12 уже выставлен, данные устоялись.
Шаг 3. На фронте такта аккумулятор и регистры фиксируют значения, счётчик команд увеличивается.
Итог: чтение команды и запись данных выполнены за один такт.
Попробуй провернуть то же самое в архитектуре фон Неймана: сначала шина везёт команду, потом — данные. Два такта вместо одного. На одной команде разница невелика, но на тысячах команд Гарвардская схема выигрывает заметно.
Резюме
1. В Гарвардской архитектуре инструкции (ROM) и данные (RAM) живут в разных устройствах памяти и ходят по разным шинам.
2. Главный плюс — параллелизм: процессор читает следующую команду и записывает данные за один такт.
3. В архитектуре фон Неймана команды и данные делят одну шину — это проще, но медленнее (узкое место фон Неймана).
4. Цепочка компьютера Ершова: PC → ROM → Splitter → Decoder → Register8/ALU8 → RAM.
5. Команда LDA загружает непосредственное значение из ROM через MUX прямо в аккумулятор.
На уровне 1.18 тебе предстоит собрать финальный компьютер Ершова: соединить счётчик команд, ROM, дешифратор, регистры, АЛУ и RAM в единую Гарвардскую схему и запустить на ней первую программу. Держи в голове главную идею: команды идут по своей шине, данные — по своей, и они не мешают друг другу.