Общий скелет компьютера

В 1945 году математик Джон фон Нейман предложил проект архитектуры компьютера, который влияет на нас до сих пор.

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


Аналогия из жизни: автоматизированная система сортировки в библиотеке

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

Вам нужно пройти следующие шаги:

Шаг 1: Ввод требований—Вы вводите название книги на компьютерном терминале библиотеки.

Шаг 2: Поиск местоположения—Система запрашивает базу данных по названию и находит, на какой полке находится книга.

Шаг 3: Извлечение книги—Роботизированная рука снимает книгу с полки.

Шаг 4: Упаковка и вывод—Книгу упаковывают, прикрепляют транспортную этикетку и отправляют на почту.

Шаг 5: Координация и управление—Всё это требует центральной диспетчерской системы для координации порядка и ритма.

Если перевести эту систему на компьютерный язык, она соответствует пяти основным компонентам архитектуры фон Неймана:

аналогия с библиотекойкомпоненты компьютераЧто он делает
Терминал запросаУстройство вводаОтправка внешней информации в компьютер
книги на полкеПамятьСклад для хранения программ и данных
Роботизированная рукаАрифметико-логическое устройство (ALU)Выполнение арифметических и логических операций
Доставка пакетовУстройство вывода (вывод)Отправляет результат из компьютера
Центральная диспетчерская системаУстройство управленияУправляет согласованной работой каждого компонента

Вы заметили? Ключ к правильной работе этой библиотечной системы — не сами отдельные компоненты, а чёткий набор правил потока данных между ними.

Точно так же суть архитектуры фон Неймана заключается втом, как компоненты соединяются и взаимодействуют。


Основной принцип: разделение труда и взаимодействие пяти компонентов

Обзор пяти основных компонентов

Архитектура фон Неймана делит компьютер на пять частей, функционально независимых, но тесно взаимодействующих:

КомпонентыАнглийскийУпрощённое пониманиеОсновные функции
Арифметическое устройствоАЛУ (арифметико-логическое устройство)«Счёты» компьютераВыполняет арифметические и логические операции, такие как сложение, вычитание, умножение, деление, AND, OR и NOT
Устройство управленияУстройство управления«Командный центр» компьютераИзвлекает команды из памяти, декодирует команды и выдаёт управляющие сигналы для управления другими компонентами
ПамятьПамять«Склад» компьютераХранит команды программы и вычислительные данные, читаемые и записываемые по адресу
Устройство вводаУстройства ввода«Глаза и уши» компьютераПодаёт внешнюю информацию (нажатия клавиш, щелчки мыши, данные датчиков) в компьютер
Устройство выводаУстройства вывода«Рот и руки» компьютераВыводить результаты вычислений в форме, воспринимаемой человеком (дисплей, печать, звук)

АЛУ и устройство управления вместе — это то, что мы обычно называем CPU (Central Processing Unit). Они — «мозг» компьютера, тогда как память и устройства ввода/вывода — «нервная система» и «органы чувств».

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

Шина данных Шина адреса Шина управления Запись данных

На рисунке ниже показана самая классическая фон-неймановская архитектура современных компьютеров. Вся система состоит из пяти частей: CPU, память, ввод, вывод и интерфейсы I/O. Внутри CPU находятся устройство управления, ALU и регистры.

CPU взаимодействует с памятью и устройствами I/O через шину данных, шину адреса и шину управления: шина адреса указывает место доступа, шина данных передаёт команды и данные, а шина управления посылает такие управляющие сигналы, как чтение, запись и прерывание. Вместе эти три шины обеспечивают обмен информацией внутри компьютера.

Три шины: магистраль данных

Связи между пятью компонентами не беспорядочны; информация передаётся упорядоченно через три группы «шин»:

Тип шиныАнглийскийЧто передаётсяНаправление
Шина данныхШина данныхСобственно команды или рабочие данныеДвунаправленная (ЦП может читать и записывать)
Шина адресаШина адресаАдрес памяти, к которому хочет обратиться ЦПОднонаправленная (ЦП выводит адрес на неё)
Шина управленияШина управленияРазрешение чтения/записи, прерывания и другие управляющие сигналыВыдаются контроллером и управляют каждым компонентом

Понимание различий между этими тремя шинами — ключ к пониманию внутренней коммуникации компьютера. Запомните так: шина адреса говорит «куда идти», шина данных отвечает за «перенос вещей», а шина управления решает «какое действие выполнить».

Концепция «хранимой программы»: душа архитектуры фон Неймана

Разделение на пять компонентов — это лишь внешний скелет. По-настоящему революционный аспект архитектуры фон Неймана заключается вконцепции хранимой программы.

До фон Неймана, чтобы выполнить задачу на компьютере, приходилось вручную вставлять и вынимать кабели, переключать тумблеры и даже заменять монтажные платы.

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

Прорыв фон Неймана:

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

Эта идея означает, что компьютер превращается из «специализированного вычислительного инструмента» в「универсальную вычислительную платформу」。

Интерактивная демонстрация: наведите курсор, чтобы исследовать пять компонентов (пример)

Наведите курсор мыши на любой компонент на схеме архитектуры ниже, и соответствующая карточка с подробным описанием справа подсветится.Нажмите кнопку «Запустить демонстрацию»и наблюдайте, как маленькая точка движется вдоль стрелок потоков данных — имитируя полный путь данных: от устройства ввода в память, затем в CPU для вычислений, обратно в память и наконец к устройству вывода.

Data flow arrow: input -> memoryData flow arrow: memory -> CPU (fetch instruction / fetch data)Data flow arrow: CPU -> memory (write-back result)Data flow arrow: memory -> outputControl signals: CPU -> Input/Output Arrow annotationData Instruction fetch / data read Control signal Блок CPU (ALU + блок управления)
CPU (ALU + блок управления)
ALU (арифметико-логическое устройство) Блок управления
блок памяти
Память Память (пример демонстрации)
Блок устройства ввода
Устройство ввода
Блок устройства вывода
Устройство вывода
Анимированная точка
Карточка подробного описания
CPU Арифметико-логическое устройство + блок управления
「Мозг」 компьютера
Память Хранение инструкций и данных
Чтение/запись по адресу
Устройство ввода Клавиатура / Мышь
Данные поступают в компьютер
Устройство вывода Монитор / Принтер
Результаты выводятся из компьютера
Нажмите кнопку, чтобы наблюдать путь потоков данных между пятью основными компонентами.

Интерактивная демонстрация: моделирование минимального компьютера с хранимой программой

Приведённый ниже код на Python моделирует минимальный компьютер фон Неймана — с АЛУ (для сложения), памятью (хранящей инструкции и данные), устройством управления (выбирающим и выполняющим инструкции последовательно в соответствии с указателем PC), и вводом/выводом.

Пожалуйста, внимательно прочитайте комментарии, затем запустите его.

Пример

"""
Минималистичный симулятор компьютера фон Неймана (пример демонстрации)
Демонстрация совместной работы пяти основных компонентов: арифметического устройства, устройства управления, памяти, ввода, вывода
"""

class VonNeumannMachine:
    """Сокращённая версия компьютера с архитектурой фон Неймана"""

    def __init__(self):
        # --- Память ---
        # Одномерный массив, начинающийся с адреса 0, хранящий как команды, так и данные
        self.memory = [0] * 256

        # --- Арифметико-логическое устройство (АЛУ) + Регистровый файл ---
        self.accumulator = 0    # Аккумулятор ACC, основной регистр АЛУ
        self.temp = 0           # Временный регистр для временного хранения операндов

        # --- Контроллер (Устройство управления) ---
        self.pc = 0             # Счётчик команд PC, хранит адрес следующей команды.
        self.running = True     # Флаг работы

        # --- Ввод / Вывод ---
        # Симулировать данные, отправляемые устройством ввода
        self.input_buffer = []
        # Симулировать данные, отображаемые устройством вывода
        self.output_buffer = []

    # ============================================================
    # Устройство ввода: записывает внешние данные по указанному адресу памяти
    # ============================================================
    def input_to_memory(self, address, value):
        print(f[Устройство ввода] Запись данных по адресу памяти {address}: {value})
        self.memory[address] = value

    # ============================================================
    # Устройство вывода: читает и отображает данные из указанного адреса памяти
    # ============================================================
    def output_from_memory(self, address):
        val = self.memory[address]
        print(f[Устройство вывода] Чтение данных из адреса памяти {address}: {val})
        self.output_buffer.append(val)

    # ============================================================
    # Память: операции чтения / записи (доступ ЦП через шину)
    # ============================================================
    def mem_read(self, address):
        Прочитать содержимое памяти по указанному адресу
        if 0 <= address < len(self.memory):
            return self.memory[address]
        raise ValueError(f"Недопустимый адрес памяти: {address}")

    def mem_write(self, address, value):
        """Записать значение в память по указанному адресу"""
        if 0 <= address < len(self.memory):
            self.memory[address] = value
        else:
            raise ValueError(f"Недопустимый адрес памяти: {address}")

    # ============================================================
    # ALU: выполняет арифметические операции
    # ============================================================
    def alu_add(self, operand):
        Операция сложения ALU: ACC = ACC + operand
        old_acc = self.accumulator
        self.accumulator += operand
        print(f"[ALU (Арифметико-логическое устройство)] сложение: {old_acc} + {operand} = {self.accumulator}")

    def alu_load(self, operand):
        """Операция загрузки ALU: загрузить непосредственное значение в ACC"""
        self.accumulator = operand
        print(f[ALU Unit] Загрузка: ACC = {operand})

    # ============================================================
    # Контроллер: извлекает инструкции, декодирует, диспетчеризует, обновляет PC
    # ============================================================
    def fetch(self):
        """Этап выборки инструкции: извлечь следующую инструкцию из памяти согласно PC"""
        instruction = self.mem_read(self.pc)
        print(f"\n<<<SEP>>> [Контроллер FETCH] PC={self.pc}, код выбранной инструкции: {instruction})
        self.pc += 1  # После выборки PC автоматически увеличивается на 1, чтобы указывать на следующую инструкцию
        return instruction

    def decode_and_execute(self, instruction):
        """
Этап декодирования + выполнения:
Мы определяем минимальный набор инструкций (код операции + операнд, смешанное кодирование):
1 LOAD immediate — Загрузить значение следующей ячейки памяти в ACC
2 ADD адрес — Добавить значение по указанному адресу в ACC
3 STORE адрес — Сохранить значение ACC по указанному адресу
255 HALT — Останов
        """

        if instruction == 1:   # LOAD
            operand = self.mem_read(self.pc)
            self.pc += 1
            print(f[Контроллер ДЕКОДИРОВАНИЕ] Инструкция: LOAD, Операнд: {operand})
            self.alu_load(operand)

        elif instruction == 2:  # ADD
            address = self.mem_read(self.pc)
            self.pc += 1
            operand = self.mem_read(address)
            print(f[Контроллер DECODE] Инструкция: ADD адрес[{address}] (значение — {operand}))
            self.alu_add(operand)

        elif instruction == 3:  # STORE
            address = self.mem_read(self.pc)
            self.pc += 1
            print(f"[Блок управления DECODE] Директива: STORE Адрес[{address}] (Значение = {self.accumulator})")
            self.mem_write(address, self.accumulator)

        elif instruction == 255:  # HALT
            print(f"[Контроллер DECODE] Инструкция: HALT (останов)")
            self.running = False

        else:
            print(f[Controller] Неизвестная инструкция: {instruction}, останов)
            self.running = False

    # ============================================================
    # Запустить полную программу
    # ============================================================
    def run(self):
        Основной цикл: повторять выборка -> декодирование -> выполнение, до останова
        print("=" * 55)
        print("Запуск минимального компьютера фон Неймана")
        print("=" * 55)
        while self.running:
            instr = self.fetch()        # Выборка инструкции
            self.decode_and_execute(instr)  # Декодировать + выполнить
        print("\n" + "=" * 55)
        print("Выполнение программы завершено, компьютер остановлен")
        print("=" * 55)


# ================================================================
# Пример программы: вычислить 10 + 20 и сохранить результат по адресу 100
# ================================================================
machine = VonNeumannMachine()

# Программа записывается в память (инструкции и данные смешаны вместе; это концепция 'хранимой программы')
# Адрес 0: LOAD 10 (код операции 1, операнд 10)
# Адрес 2: ADD 100 (код операции 2, операнд 100, означающий извлечь слагаемое из адреса 100)
# Адрес 4: STORE 200 (код операции 3, операнд 200, указывающий, что результат сохраняется по адресу 200)
# Адрес 6: HALT (код операции 255)
machine.memory[0] = 1
machine.memory[1] = 10     # Операнд LOAD: непосредственное значение 10
machine.memory[2] = 2
machine.memory[3] = 100    # Операнд ADD: адрес 100, где расположены данные
machine.memory[4] = 3
machine.memory[5] = 200    # Операнд STORE: адрес 200, куда сохраняется результат
machine.memory[6] = 255    # HALT

# Сохранить слагаемое 20 по адресу 100 (имитация записи данных устройством ввода)
machine.input_to_memory(100, 20)

# Запустить программу
machine.run()

# Просмотр результатов
result = machine.mem_read(200)
print(f"\nИтоговый результат: значение по адресу памяти 200 = {result})
machine.output_from_memory(200)
print(f"Буфер устройства вывода: {machine.output_buffer}")

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


Итоги и проверка

Итог в одном предложении

Архитектура фон Неймана делит компьютер на пять частей: арифметическое устройство, устройство управления, память, устройство ввода и устройство вывода, соединённые тремя группами шин, и хранит последовательность команд и данные в одной и той же памяти. В ней CPU автоматически извлекает инструкции и выполняет их в заданной последовательности.

Вопросы для самопроверки

Вопрос 1Какие два из пяти основных компонентов архитектуры фон Неймана вместе называются CPU?

  • A. Арифметическое устройство и память
  • B. Арифметическое устройство и устройство управления
  • C. Устройство управления и память
  • D. Устройства ввода и устройства вывода

Правильный ответ: B

Вопрос 2Какова функция шины адреса? Каково направление передачи данных по ней?

  • A. Передача результатов вычислений; двунаправленная
  • B. Передача сигналов управления; выдаются устройством управления
  • C. Передача адресов памяти; от процессора к памяти (однонаправленная)
  • D. Передача команд и данных; двунаправленная

Правильный ответ: C. Шина адреса передаёт адресную информацию из процессора в память и является однонаправленной.

Вопрос 3В чём основное значение концепции «хранимой программы»?

  • A. С тех пор компьютерам больше не требовалось арифметическое устройство
  • B. Модификация программного обеспечения требует лишь изменения содержимого памяти, без необходимости изменять аппаратное обеспечение
  • C. Объём памяти больше, чем у CPU
  • D. Устройства ввода и устройства вывода можно объединить

Правильный ответ: B. Хранимая программа превращает компьютер из специализированного устройства в универсальную платформу, а программное обеспечение можно гибко заменять.

Другие расширения