Вступление

Здесь я постараюсь рассказать про строение и работу процессора на примере x86–64 архитектуры.

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

Я решил поделиться своими заметками, так как возможно кому-то это может показаться полезным. На детальность информации не претендую, но не против конструктивной критики.

Вот довольно неплохие видео, которые noob friendly:

1) https://www.youtube.com/watch?v=ubsZ9MO9qkU

2) https://www.youtube.com/watch?v=aNVMpiyeY_U&t=280s

Устройство процессора (схематически)

Процессор
Процессор
Ядро
Ядро

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

Процесс обработки данных процессором (при прочтении поглядывай на картинки)

Центральный процессор (CPU, Central Processing Unit) — это основной компонент устройств, который выполняет все вычисления и логические операции, необходимые для работы программ.

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

Если он не находит данные там, то он генерирует сигнал на шине адреса, указывающий физический адрес памяти ОЗУ, по которому нужно прочитать данные. Этот сигнал на шине адреса генерируется процессором и передается контроллеру памяти.

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

То есть отправляем в ОЗУ адрес по шине адреса, а получаем данные по шине данных.

По шине данных информация помещается в кэш L3.

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

Кэш L1 часто разделяется на две части: кэш данных и кэш инструкций. Инструкции, которые передаются вместе с данными, попадают в кэш инструкций, а данные оказываются в кэше данных.

После того как данные и инструкции попадают в соответствующие кэши L1, инструкции отправляются в декодер.

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

Данные из кэша данных могут попадать в буферы загрузки (load buffers) для последующей обработки.

А декодированные инструкции направляются в буфер переупорядочевания (reorder buffer), который решает проблемы конфликтов данных и зависимостей инструкций, и может временно изменять порядок выполнения инструкций, чтобы обеспечить корректность выполнения программы.

Затем планировщик направляет инструкции в исполнительные или вычислительные блоки (ALU, FPU, VPU и так далее)

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

Каждое ядро может обрабатывать несколько потоков инструкций (обычно 2) за счёт технологий Hyper-Threading и Simultaneous Multi-Threading.

Данные из буферов поступления обычно загружаются в регистры общего назначения (если требуется).

В этих регистрах данные доступны для последующей обработки с использованием арифметико-логического устройства (ALU) или других вычислительных блоков процессора, таких как блоки с плавающей точкой (FPU) или векторные блоки (VPU).

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

Далее данные перемещаются в иерархии выше: в кэш L2, а затем в кэш L3.

В конечном счете, данные могут быть сохранены обратно в оперативную память (RAM), если это необходимо.

Описание компонентов

Устройство управления (Control Unit)

Управляет выполнением инструкций, координируя работу других компонентов.

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

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

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

  3. Счётчик инструкций: Отслеживает текущую выполняемую инструкцию и управляет последовательностью исполнения инструкций внутри процессора.

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

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

Планировщик (Scheduler):

  • Планировщик отвечает за распределение микроопераций (micro-ops) между различными исполнительными блоками процессора, такими как ALU и FPU.

  • Он определяет порядок исполнения микроопераций, стараясь максимально эффективно использовать ресурсы процессора и минимизировать время простоя.

ALU (Arithmetic Logic Unit):

  • Выполняет арифметические операции (сложение, вычитание и т.д.).

  • Выполняет логические операции (AND, OR, XOR и т.д.).

FPU (Floating Point Unit):

Выполняет операции с плавающей запятой.

VPU (Vector Processing Unit):

Выполняет операций с векторными данными.

MMU (Memory Management Unit):

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

NPU (Neural Processing Unit):

Устройство, специализированное на выполнении операций, связанных с нейронными сетями и искусственным интеллектом. (добавил из-за хайпа)

Регистры:

Материал (англ): https://wiki.osdev.org/CPU_Registers_x86

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

Триггер (flip-flop) — это элементарная цифровая ячейка, способная хранить один бит информации (0 или 1).

Регистры являются самой быстрой памятью в компьютере, поскольку они находятся непосредственно в процессоре и имеют непосредственный доступ к ALU.

Регистры делятся на регистры общего назначения и регистры специального назначения.

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

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

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

Регистры общего назначения имеют размер, соответствующий разрядности процессора. А регистры специального назначения уже зависят от реализации того или иного процессора. Например, в некоторых архитектурах регистр управления кэш-памятью может быть 64-битным даже в 32-битных процессорах.

Регистры общего назначения:

  1. RAX (Accumulator Register):

    Используется для арифметических, логических операций и операций ввода-вывода.

  2. RBX (Base Register):

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

  3. RCX (Counter Register):

    Используется в операциях цикла и как счетчик в командах REP и LOOP.

  4. RDX (Data Register):

    Используется в арифметических операциях, особенно в умножении и делении.

  5. RSI (Source Index):

    Используется для указания на исходный адрес при операциях с памятью (например, при копировании данных).

  6. RDI (Destination Index):

    Используется для указания на адрес назначения при операциях с памятью.

  7. R8-R15 (Дополнительные регистры):

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

Специальные регистры:

  1. RSP (Stack Pointer):

    Указывает на вершину стека.

  2. RBP (Base Pointer):

    Используется для доступа к параметрам и локальным переменным в стеке.

  3. CS (Code Segment):

    Хранит базовый адрес сегмента кода в ОЗУ, откуда процессор считывает команды для выполнения. Если проводить аналогию между кодом и книгой, то CS указывает на номер страницы в книге (программе)

  4. RIP (Instruction Pointer):

    Указывает на следующую инструкцию, которую должен выполнить процессор. Если проводить аналогию между кодом и книгой, то RIP указывает на номер строки на странице, которая указана в CS.

  5. FLAGS (или RFLAGS в 64-разрядной системе):

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

«Регистры в регистрах» ©Xzibit

Ранее существовали 16-битные регистры, такие как AX, BX, CX и DX, каждый из которых мог быть разделён на два 8-битных регистра: старший и младший. Например, регистр AX разделён на AH (старший байт) и AL (младший байт).

При расширении до 32 бит, 16-битные регистры стали частью новых 32-битных регистров. Например, регистр AX был включён в регистр EAX, где младшие 16 бит EAX соответствуют регистру AX.

При переходе к 64-битным регистрациям, 32-битные регистры (например, EAX) включены в более широкий регистр — RAX. В случае регистра RAX, младшие 32 бита этого регистра являются регистром EAX.

Таким образом, 8-битные регистры AH и AL всё также сохраняют свою функциональность и доступны в составе более широких регистров новых архитектур.

Сделано это в основном для обеспечения обратной совместимости.

; Использование регистра RAX для арифметических операций
    mov rax, 5          ; Кладем 5 в регистр RAX
    add rax, 10         ; Добавляем 10 к регистру RAX (итог: 15)

; Использование регистра RBX для хранения данных и арифметических операций
    mov rbx, rax        ; Копируем значение RAX в RBX (RBX теперь 15)
    sub rbx, 3          ; Вычитаем 3 из RBX (итог: 12)

; Использование регистра RCX в качестве счетчика
    mov rcx, 3          ; Кладем 3 в регистр RCX
loop_start:
    dec rcx             ; Уменьшаем RCX на 1
    jz loop_end         ; Если RCX = 0, переходим на метку loop_end
    add rax, rcx        ; Добавляем RCX к RAX (2 + 15, затем 1 + 17, в итоге RAX хранит 18)
    jmp loop_start      ; Переходим на метку loop_start
loop_end:

; Использование регистра RDX для умножения и деления
    mov rdx, 2          ; Кладем 2 в регистр RDX
    imul rax, rdx       ; Умножаем RAX на RDX (итог: 36)

Кэш-память:

  • L1: Первый уровень кэша, самый быстрый и маленький по объему.

  • L2: Второй уровень кэша, более медленный, но большего объема.

  • L3: Третий уровень кэша, ещё более медленный, но ещё большего объема, чем L2 и быстрее оперативной памяти. L3 кэш обычно является общим для всех ядер в многоядерном процессоре. Это означает, что все ядра процессора могут иметь доступ к данным, хранящимся в L3 кэше, что полезно для снижения задержек в доступе к данным между ядрами.

  • L4 — Тоже самое что и L3, но ещё медленнее (но все равно быстрее оперативной памяти) и объёмнее, используется только в высокопроизводительных системах, например, серверах.

Системная шина

Шина представляетсобой физический канал передачи данных и управляющих сигналов между различными компонентами компьютера. Все данные между процессором, регистрами, памятью и I/O‑устройствами (устройствами input‑output) передаются по шинам. Чтобы загрузить в память только что обработанные данные, процессор помещает адрес в шину адреса и данные в шину данных. Потом нужно дать разрешение на запись на шине управления.

Шина данных (Data Bus):

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

  • Ширина шины данных (data bus width) измеряется в битах и часто соответствует разрядности процессора. Это количество бит, которые могут передаваться по шине данных одновременно. Например, 64-битная шина данных может передавать 64 бита данных за один раз.

  • Важно отметить, что ширина шины данных и разрядность процессора часто совпадают, но не всегда. Например, процессор может быть 32-битным, но иметь 64-битную шину данных для повышения производительности при работе с памятью.

Шина адреса (Address Bus):

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

  • Ширина шины адреса определяет диапазон адресов, который процессор может обращаться. Например, 32-битная шина адреса позволяет обращаться к 2^32 (4 ГБ) адресам.

Шина управления (Control Bus):

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

  • Она включает сигналы для чтения/записи данных, инициализации операций, сигналы прерывания и другие управляющие сигналы, необходимые для координации работы системы.

Тактирование процессора

Один такт процессора (или тактовый цикл) — это единица времени, определяемая одним импульсом тактового сигнала процессора.

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

Тактовая частота — количество тактов за секунду.

Частота нынешних процессоров измеряется в ГГц (Гигагерцы). 1 ГГц = 10⁹ Гц — миллиард тактов.

Продолжительность одного такта определяется тактовой частотой процессора. Например, если процессор работает на частоте 3 ГГц, это означает, что один такт длится примерно 0.33 наносекунды (1 / 3,000,000,000 секунды).

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

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

Выполнение инструкций

Инструкции хранятся в ОЗУ в последовательном порядке. Для гипотетического процессора инструкция состоит из кода операции и адреса памяти/регистра. Внутри управляющего устройства есть два регистра инструкций, в которые загружается код команды и адрес текущей исполняемой команды. Ещё в процессоре есть дополнительные регистры, которые хранят в себе последние 4 бита выполненных инструкций.

Ниже рассмотрен пример набора команд (на псевдокоде), который суммирует два числа:

  1. LOAD_A 8. Это команда сохраняет в ОЗУ данные, скажем, <1100 1000>. Первые 4 бита — код операции, следую. Именно он определяет инструкцию. Эти данные помещаются в регистры инструкций УУ. Команда декодируется в инструкцию load_A — поместить данные 1000(последние 4 бита команды) в регистр A.

  2. LOAD_B 2. Ситуация, аналогичная прошлой. Здесь помещается число 2 (0010) в регистр B.

  3. ADD B A. Команда суммирует два числа (точнее прибавляет значение регистра B в регистр A). УУ сообщает АЛУ, что нужно выполнить операцию суммирования и поместить результат обратно в регистр A.

  4. STORE_A 23. Сохраняем значение регистра A в ячейку памяти с адресом 23.

Вот такие операции нужны, чтобы сложить два числа.

Кэш

Для начала примем один факт - с ростом объёма кэша возрастает и задержка доступа.

Причина в увеличении времени на определение пути к нужной ячейке памяти внутри большого кэша. Поэтому по скорости L1 > L2 > L3 > ОЗУ, но с объёмом ровно наоборот. Такая иерархия позволяет процессоре работать в балансе между скоростью и доступным объемом памяти.

У процессора есть механизм сохранения инструкций в кэш. Как мы выяснили ранее, за секунду процессор может выполнить миллиарды инструкций. Поэтому если бы каждая инструкция хранилась в ОЗУ, то её изъятие оттуда занимало бы больше времени, чем её обработка. Поэтому для ускорения работы процессор хранит часть инструкций и данных в кэше для ускорения доступа к наиболее часто используемым инструкциям и данным.

Строка или кэш-линия в контексте кэш-памяти (cache line) — это последовательная группа байтов. Она представляет собой минимальную единицу данных, которую кэш может загружать из основной памяти и сохранять. Длина строки обычно составляет 32, 64 или 128 байт, в зависимости от архитектуры процессора и кэш-памяти.

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

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

Подробнее

Грязные биты (dirty bits) — это флаги в кэш-памяти, которые указывают на то, что данные в кэше были изменены (модифицированы) по сравнению с их копией в основной памяти (ОЗУ). Когда данные в кэше и основной памяти не совпадают, они считаются «грязными».

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

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

Поток инструкций

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

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

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

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

Разрядность процессора

Основные аспекты разрядности процессора

Ширина данных:

  • Разрядность процессора указывает на количество бит, которые процессор может обработать за один цикл. Например, 32-битный процессор может работать с 32-битными числами или адресами памяти. То есть длина слова будет 32 бита.

  • Машинное слово — это единица данных, с которой процессор работает за один такт. Длина слова соответствует разрядности процессора. Термин «слово» пришел из ранней компьютерной науки и электроники.

Адресное пространство:

Разрядность также определяет максимальный объем памяти, который процессор может адресовать. 32-битный процессор может адресовать до 4 ГБ оперативной памяти (2^32 байт), тогда как 64-битный процессор может адресовать гораздо больше — до 16 эксабайт (2^64 байт), хотя современные операционные системы и аппаратное обеспечение обычно ограничивают этот объем до нескольких терабайт.

Регистр процессора:

Разрядность процессора определяет размер регистров. В 32-битном процессоре регистры имеют размер 32 бита, в 64-битном — 64 бита (касается не всех регистров, а по большей части регистров общего назначения).

Почему x86?

  1. Intel 8086 (1978 год): Этот процессор был первым 16-битным процессором в семействе x86, который заложил фундамент архитектуры x86.

  2. Intel 80386 (1985 год): Этот процессор продолжил развитие архитектуры x86 и добавил поддержку 32-битной адресации и данных. Он был очень важным для современных операционных систем и приложений, так как открыл путь к полноценной поддержке многозадачности и сложных вычислений.

  3. AMD Opteron (2003): В 2003 году AMD представила процессоры с архитектурой x86-64 (также известной как AMD64), которые поддерживают 64-битные вычисления, но также и имеют обратную совместимость с x86, поэтому такое название: x86-64. Хотя до сих пор принято называть такие процессоры x86-ыми. Intel просто лицензировали технологию AMD, чуть-чуть доработали, обозвали EM64T, но по сути это та же AMD64, поэтому под архитектуру x86-64 программы обычно обозначаются обычно как AMD64.

ARM

История и развитие ARM процессоров

  1. Основание и начало: ARM была разработана в 1980-х годах компанией Acorn Computers Ltd (Великобритания) в ответ на необходимость компактных, энергоэффективных и высокопроизводительных процессоров для использования в персональных компьютерах.

  2. Переход в мобильные устройства: В конце 1980-х и начале 1990-х годов ARM начала активно использоваться в мобильных устройствах, таких как КПК и мобильные телефоны. Эта архитектура была особенно привлекательной из-за своей энергоэффективности, что способствовало продолжительности работы от аккумулятора.

  3. Эволюция и расширение применения: С течением времени ARM стала доминирующей архитектурой в мобильной индустрии. Процессоры ARM были адаптированы для использования в различных устройствах, от смартфонов и планшетов до IoT устройств и встраиваемых систем.

  4. Развитие в вычислительных системах: В последние годы ARM также начала проникать в область серверных решений с целью предложить более энергоэффективные альтернативы для центров обработки данных (ЦОД). Это направление включает в себя процессоры, такие как ARMv8-A, которые поддерживают 64-битные вычисления и являются конкурентами для x86-64 в сфере серверных вычислений.

ARM vs x86

Исходя из сухих данных, развитие ARM архитектуры может обеспечить ей доминирование на рынке по производительности/энергоэффективности, тем более, что даже Apple Silicon M4 вполне себе способнен конкурировать с некоторыми современными десктопными процессорами.

Но наследие ПО под x86 заставляет нас оставаться на довольно древней и далеко не идеальной x86-64 архитектуре.

Комментарии (16)


  1. SIISII
    01.11.2024 08:15

    Вообще-то, 8086/88, будучи 16-разрядными, могли адресовать 1 Мбайт памяти. А ИБМовская Система 360, будучи 32-разрядной, могла адресовать только 16 Мбайт памяти. А 16-разрядная PDP-11 в зависимости от варианта -- 64 Кбайта, 256 Кбайт или 4 Мбайта. Дело в том, что адрес не обязательно совпадает с разрядностью процессора -- в т.ч. логический (виртуальный) адрес, а о физическом и говорить нечего.


    1. daniil_kulikov Автор
      01.11.2024 08:15

      Да, вы правы, спасибо! Решил и вовсе убрать информацию об этом, так как для целей этой статьи она избыточна


      1. SIISII
        01.11.2024 08:15

        Кстати, ещё про разрядность. Одно дело разрядность с точки зрения программиста, и другое -- физическая разрядность. Одно с другим тоже не очень-то связаны. Разрядность с точки зрения программиста определяется архитектурой (скажем, IA-32 -- 32-разрядная, а её расширение до AMD64 дало в результате современную 64-разрядную архитектуру). А вот физическая определяется разработчиками проца исходя из требований к производительности и т.п. Сейчас они если не всегда, то почти всегда совпадают, но это не является безусловно необходимым. Скажем, Система 360 -- 32-разрядная, однако её процессоры внутри были и 8-, и 16-, и 32-, и 64-разрядными в зависимости от производительности конкретной модели.


  1. TooBigBigs
    01.11.2024 08:15

    но не против конструктивной критики.

    Возьмем картинки:

    • на первой картинке кэш L3 находится справа, а ядра - слева. На второй наоборот, что мгновенно сбивает читателя;

    • на обеих картинках смешан русский и английский язык, а в тексте используются русские слова без перевода, таким образом для читателя это превращается в терминологическую кашу;

    • на обеих картинках заглавные и строчные буквы в написании слов применяются бессистемно.

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

    Вследствие совокупной небрежности, воспринимать этот текст сложно, а в вырванных из контекста фразах вообще сложно понять смысл:

    Инструкции, которые передаются вместе с данными, попадают в кэш инструкций, а данные оказываются в кэше данных.

    А что происходит с инструкциями, которые передаются отдельно о данных? Или так не бывает? И в чем вообще смысл разделять их, инструкции это разве не данные, а что это тогда? И что такое кэш, в который надо "попадать"?


    1. daniil_kulikov Автор
      01.11.2024 08:15

      Спасибо за замечения! Смешно получилось с сочетанием языков на картинках, как в меме: "смотря какие details"))))
      Ну а вообще, изначально такая асимметрия в картинках из-за более привычного расположения ОЗУ справа от ЦП, но при этом при просмтре строения ядра привычнее читать схему слева направо. С учётом схематичности изображений, а также с разнообразности строения материнских плат, особенно серверных, решил поменять картинки, чтобы всё читалось слева направо.


  1. Armmaster
    01.11.2024 08:15

    Быстродействие компьютера определяется тактовой частотой его процессора.

    Нет. Быстродействие компьютера определяется множеством факторов. Например, скоростью работы дисковой подсистемы, если вы с файлами работаете. Если же мы хотим упростить быстродействие компьютера до быстродействия процессора, то оно опредляется не только частотой, а ещё и таким показателем как IPC (Instructions per Cycle)

    RISC (Reduced Instruction Set Computing)

    Преимущества:

    1. Простота инструкций: Инструкции в RISC-архитектуре проще и быстрее выполняются, что позволяет увеличить производительность за счет более быстрого цикла выполнения команд.

    2. Конвейеризация: За счет простоты инструкций конвейеризация (pipelining) становится более эффективной, что позволяет выполнить больше команд за такт.

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

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

    В современном мире все приведённые преимущества неверны.

    Недостатки:

    Сложности компиляции: Компиляторы должны быть более умными, чтобы эффективно использовать простые инструкции для сложных задач.

    Скажем так, в современном мире это тоже не так.

    CISC (Complex Instruction Set Computing)

    Преимущества:

    Многофункциональность: Поддержка множества инструкций и режимов работы позволяет процессорам x86-64 быть очень универсальными и адаптивными для разных задач.

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

    Недостатки:

    1. Сложность и энергопотребление: Более сложные инструкции требуют больше транзисторов и более сложной логики, что увеличивает энергопотребление и тепловыделение.

    2. Наследие: Поддержка устаревших инструкций и режимов может накладывать дополнительные ограничения на архитектуру, делая ее менее эффективной по сравнению с RISC.

    Это тоже в современном мире неверно. Это вообще странно писать в ситуации, когда самые высокопроизводительные процессоры на текущий момент - CISC процессоры архитектуры x86.


    1. SIISII
      01.11.2024 08:15

      самые высокопроизводительные процессоры на текущий момент - CISC процессоры архитектуры x86

      Вообще, от задачи зависит. Скажем, в роли матричной числодробилки даже посредственный графический процессор порвёт любой AMD64. Если всякие там массовые шифрования AES и всё такое прочее, то, вполне возможно, победителем будет проц z/Architecture, где подобные операции делаются одной командой (и он, есно, CISC, ведущий свою родословную от Системы 360). Но, в любом случае, проблематично назвать "самый-самый", а уж без конкретизации рода задач -- и вовсе невозможно.


      1. Armmaster
        01.11.2024 08:15

        В данной статье говорится про General Purpose CPU, очевидно. Поэтому мой комментарий только к ним и относится. Понятно что есть ASIC'и, которые для специальных задач и предназначены, но это совсем другая история, не имеющая отношения к данной статье.


  1. gscdlr
    01.11.2024 08:15

    Можно придраться ко многим фразам, но, раз уж название "для самых маленьких", то сойдёт.

    Однако вывод просто противоречит фактам и мимо него нельзя просто пройти, проигнорировав. Например, в том, что достигнув производительности десктопных х86, arm по tdp и энергоэффективности сравнялись с x86. С другой стороны, Intel выпустила линейку процессоров Lunar Lake, спроектированную под тонкие, лёгкие и автономноые ультрабуки. И это у них получилось. Lunar Lake по производительности выступают на равных или быстрее соответствующих чипов Qualcomm и Apple, превосходя их по энергоэффективности.
    Рано хоронить х86.


  1. firehacker
    01.11.2024 08:15

    Хранит базовый адрес сегмента кода в ОЗУ

    Не адрес, а селектор. А селектор (в защищённом режиме) это флаговые биты плюс индекс в таблице — таблице дескрипторов сегментов.

    И уже в дескрипторе сегмента хранится базовый адрес сегмента.

    так как открыл путь к полноценной поддержке многозадачности

    А чем неполноценна многозадачность в 286? В 386 в плане многозадачности появился только режим Virtual 8086 mode. Остальные новые фишки касаются в основном MMU, например, введение страничной организации и дополнительного уровня трансляции адресов (линейных) в физические.


    1. SIISII
      01.11.2024 08:15

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


      1. firehacker
        01.11.2024 08:15

        Ещё больший процент не знают и не понимает концепцию сегментов в защищенном режиме, имея представление о сегментах на основе сегментов реального режима :-(


        1. SIISII
          01.11.2024 08:15

          Ну, для этого нужно погружаться конкретно в 8086, 80286 и IA-32 (80386 и далее): эта фишка -- их черта, а в подавляющем большинстве процессорных архитектур такого нет. (Слово "сегмент" может использоваться, но имеет совершенно другой смысл; скажем, в Системе 370 сегменты -- это верхний уровень деления виртуальной памяти на блоки, нижний уровень -- страницы; управляющий регистр процессора указывает адрес таблицы сегментов, в элементах таблицы сегментов содержатся адреса таблиц страниц, а уже в элементах таблиц страниц -- реальные адреса страниц в памяти.)

          Ну и, Вам, не сомневаюсь, известно (а вот многим другим -- не очень), что, хотя в IA-32 сегментация является обязательной, но сегменты настраиваются таким образом, что получается не сегментированное, а плоское виртуальное адресное пространство -- т.е., по сути, сегментация в сколько-нибудь массовых ОС, включая Винду и Линух, не используется, хотя технически имеется (а в AMD64 её по этой причине и выпилили). Интересно, во всяких "танненбаумах" или что там используется в учебном процессе по осям, про неё сколько-нибудь внятно говорится?..


          1. firehacker
            01.11.2024 08:15

            т.е., по сути, сегментация в сколько-нибудь массовых ОС, включая Винду и Линух, не используется

            Но это не совсем так.

            Windows в user-mode создаёт небольшой сегмент с базой, указывающей на thread environment block (TEB) / thread information block (TIB), а селектор этого сегмента загружает в регистр FS.

            Отсюда обращения к FS:[0] для работы с SEH-цепочкой, работа виндового TLS на это завязано, да и куча кода в kernel32.dll и иже с ними лежет в TEB для множества разных целей.

            В Linux-е FS используется для TLS, а GS доступен для использования.

            В этом объёме сегментацию не выпилили даже в AMD64.

            Но в целом, тот факт, что Intel предложила миру эту классную концепцию, а её в полной мере никто не заценил и не использовал, вызывает у меня моральные страдания. У меня даже есть мысль написать статью о том, каким мог бы быть мир, если бы сегменты использовали в хвост и в гриву (в защищённом режиме и 32-битном режиме).

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

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


            1. SIISII
              01.11.2024 08:15

              Но это не совсем так.

              Windows в user-mode создаёт небольшой сегмент с базой, указывающей на thread environment block (TEB) / thread information block (TIB), а селектор этого сегмента загружает в регистр FS.

              Отсюда обращения к FS:[0] для работы с SEH-цепочкой, работа виндового TLS на это завязано, да и куча кода в kernel32.dll и иже с ними лежет в TEB для множества разных целей.

              В Linux-е FS используется для TLS, а GS доступен для использования.

              Я в курсе про это. Но реально сие использование сегментации -- совсем не такое, как задумывалось создателями архитектуры. По сути, FS и GS используются как дополнительные базовые регистры -- как можно использовать, например, EBX -- ведь они задают положение некоей области в едином плоском виртуальном адресном пространстве. В таком качестве они используются и в AMD64, где сегментация как таковая выпилена полностью. В общем, это довольно остроумное извлечение пользы из, скажем так, малоудачного аппаратного механизма, который сам по себе никому не нужен.

              Кстати, потенциально сегментацию можно было бы использовать для относительно эффективной реализации по-настоящему микроядерной ОС, но и там он... слишком заумный и не особо эффективный. Лично мне больше нравится механизм множества адресных пространств у IBMовских мэйнфреймов (стал появляться в поздних вариантах Системы 370 и в дальнейшем развивался; правда, используется не в собственно ОС, а для реализации серверов приложений или чего-то в этом роде).


  1. firehacker
    01.11.2024 08:15

    /del