«В жизни есть только три вещи, от которых некуда деться:
смерть, налоги и желание иметь более быстрый процессор!»
краткий обзор, написанный не более, чем для общего понимания ситуации
Материал нисколько не претендует на роль учебника, и не преследует никаких других целей, кроме как дать желающим общее представление о работе современных компьютеров, с рассказом о том, откуда что пошло, и почему всё сформировалось в том виде, в котором мы его сегодня наблюдаем.
Понимая, что читать сей опус будут люди с разным уровнем специальных знаний с одной стороны и с разной степенью заинтересованности в деталях и подробностях с другой — я сознательно оставляю в тексте только минимальное популярное изложение, убирая все тонкости и детали в сноски и давая ссылки на внешние материалы (нет смысла переписывать Википедию). Кому нужно больше, чем в основном тексте — добро пожаловать в сноски и по ссылкам. Но это не обязательно.
«Зри в корень!»
Сколь веревочка не вейся, а в конечном итоге — под всеми красивыми интерфейсами, операционными системами, сложнейшими программами и их комплексами, внутри всех облачных сервисов и настольных компьютеров находится то, что все эти чудеса делает реальностью. Чтобы всё это сделалось возможным, все это должен отработать сложно организованный кусок кремния (с примесями), который называется процессор (микропроцессор). Именно процессор и есть сердце любого цифрового устройства, от калькулятора до суперкомпьютеров и облаков гиперскейлеров. Вот о том, что такое процессор, какие они бывают и что у них внутри — мы сейчас и поговорим.
И начнем мы с процессоров компьютерных и околокомпьютерных — во-первых, потому что у них более длительная история, позволяющая проследить, как и почему сформировался современный облик процессоров и вычислительных систем, а во-вторых этот рынок гораздо менее фрагментирован, что упрощает изложение, не слишком соблазняя углубляться в детали и тонкие различия. Ну и в-третьих, при меньшей фрагментированности спектра процессорных архитектур — «настольный» и серверный сегменты вычислений гораздо более вариативны в части архитектур системных, что позволит нам рассмотреть проблему со всех сторон.
Что такое процессор?
Процессор это программно-управляемый набор из трех логических элементов («И» «ИЛИ» «НЕ») и их комбинаций, реализующий определенные действия с наборами данных определенной длины, представленными в виде последовательностей из двух логических состояний («0» и «1») Собственно, все. Дальше начинаются детали и подробности.
Какие подробности? Давайте смотреть.
- Первым параметром, определяющим процессор, является его разрядность, длина последовательностей, с которыми он может оперировать в одной команде. Как правило, разрядность процессора кратна общепринятой единице двоичной информации, байту состоящему из 8 нулей и единиц, причем исторически сложилось так, что на каждой итерации разрядность удваивается. Таким образом, процессоры бывают 8- 16- 32- и 64-разрядными (бывают и 4-разрядные, но это уже история).
- Второй параметр — как часто (сколько раз в секунду) процессор может делать эти операции, в смысле, его тактовая частота. Измеряется в единицах частоты – герцах (кило-, мега- и гигагерцах).
На этом простые вещи кончаются — и начинается самое интересное. Если бы производительность можно было посчитать, просто перемножив разрядность счетчика на частоту (количество операций в секунду), то я бы и не стал затевать этот текст. Дело в том, что и одинаковые команды в разных процессорах выполняются за разное количество тактов, и количество одновременно исполняемых команд разного типа у разных процессоров может быть разным, и перемещение данных в компьютере происходит не мгновенно, а в соответствии с довольно сложными правилами (придуманными, впрочем, для ускорения процесса). В общем, давайте попробуем разобраться, как все это работает.
Интегральным показателем, позволяющим оценить совершенство архитектуры процессора и примерно понимать его производительность является количество инструкций, которое он может исполнить за один такт. Он так и называется, этот параметр: instructions per cycle (IPC). Этот параметр зависит от огромного количества нюансов и его реальное значение носит усредненный статистический характер. Дело в том, что на разных последовательностях команд один и тот же процессор может выполнять разное количество инструкций за такт. Особенный интерес представляет отношение реально достижимого темпа исполнения к теоретически максимальному значению, эту безразмерную величину после усреднения можно считать КПД архитектуры и конкретного процессора.
Почему конкретного процессора? Потому что есть, например, такой фокус: КПД одного и того же процессора при увеличении тактовой частоты уменьшается. Почему? Эту странность мы рассмотрим ниже, а пока просто запомните эту штуку.
Когда-то давным-давно, когда процессоры были простыми, они — в реализации с классическим набором команд (CISC) — получали на вход инструкцию, которая последовательно запускала разные схемы передачи сигналов, обрабатывая их на универсальном арифметически-логическом устройстве (АЛУ). Понятно, что разные команды требовали различных последовательностей исполнения, и для микропроцессора Intel 8086, например, команды требовали от 4 до 180+ тактов (деление). Альтернативное решение, известное как RISC предусматривало разложение алгоритма на элементарные команды фиксированного формата, исполняемые за фиксированное количество тактов, но одна сложная команда CISC в RISC-представлении выглядела как последовательность простых команд, иногда довольно длинная. С одной стороны, размер программы получался больше, а с другой — сам процессор имел гораздо более простую структуру, на которой было легче достигать высоких частот.
Схематическое изображение конвейера процессора 486.
Современные же процессоры представляют собой комбинацию этих двух технологий: поступающие в процессор высокоуровневые команды преобразуются в RISC-подобную микропрограмму, которая уже исполняется собственно ядром процессора. В чем прелесть такого подхода? Имея слой такой аппаратной трансляции можно практически свободно менять внутреннюю архитектуру процессора, при сохранении совместимости с существующей «внешней» системой команд и наоборот, вводить новые команды, не трогая исполнительные конвейеры. Как совершенствовать процессоры, добиваясь увеличения параметра IPC? Например, просто увеличивая количество исполнительных устройств можно запускать на исполнение сразу несколько микропрограмм исходя из наличия свободных исполнительных устройств. Процессор, способный нарушать последовательность команд и параллельно исполнять более одной команды называется «суперскалярным».
Второй путь совершенствования архитектуры лежит в разложении исполнения команды в последовательность упрощенных по схемотехнике этапов исполнения. Первый х86 процессор с конвейерным исполнением, i486 имел, к примеру, пять стадий:
- выборка инструкции,
• декодирование инструкции,
• декодирование адресов операндов инструкции,
• выполнение команды,
• запись результата выполнения инструкции
В чем прелесть? Прелесть в том, что, когда команда «1» уже выполнена и производится запись ее результатов в память — команда «2» находится на этапе исполнения, команда «3» уже декодирована и процессор выясняет физические адреса операндов, одновременно декодируя команду «4» и уже выбирая из памяти команду «5», в результате чего данные на выходе появляются пропорционально времени исполнения на самой сложной части конвейера, которая в любом случае всего лишь часть от общего времени исполнения. Для i486 это время в среднем составляло 10-15 тактов между выходом очередных результатов. Именно этим обусловлен кратный рывок производительности i486 против i386 при равной частоте. Потому что i386 должен был полностью завершить исполнение команды «1» до того, как начнется выборка команды «2», все ~20-50 тактов. Про команды «3», «4» и «5» речь, заметьте, еще даже и не заходила. Конечно, сложность схем на стадиях короткого конвейера тоже была заметной, поэтому длина конвейера с тех пор почти непрерывно растет, что упрощает схемотехнику на каждой «станции» конвейера, а это, в свою очередь, позволяет увеличить частоту их работы.
Как видите, разбиение исполнения команды на более простые операции удлинило конвейер Pentium 4 вдвое – что позволило в те же два раза (пропорционально упрощению схемотехники отдельных стадий конвейера) сразу увеличить и частоту процессора при том же техпроцессе 180 нанометров.
К настоящему времени совершенство конвейеризации выполнения достигло такой степени, что для 13-15 стадийного конвейера результат исполнения команд появляется на выходе в каждом такте. Т.е., когда мы получаем результат исполнения некоторой команды номер N — на входе в исполнительную систему уже подается команда с номером N+15 к текущей, результаты которой мы получим через 15 тактов (и спустя столько же результатов команд с номерами N+1, N+2 и так далее).
В результате сочетания обоих путей совершенствования микроархитектуры современный процессор представляет собой набор из нескольких специализированных конвейеризованных исполнительных модулей, работающих параллельно. Так, например, ядро процессора AMD архитектуры Zen состоит из четырех конвейеризованных блоков целочисленных операций (ALU) и одного модуля операций с плавающей запятой (FPU), в котором есть два блока сложения (ADD) и два блока умножения (MUL). Таким образом, теоретически процессор может выдавать до шести результатов за такт, а вот декодер умеет запускать на исполнение не больше четырех команд в каждом такте (разработчики знают об ограничениях исполнения и не закладывают лишнего). Практически же измеренный параметр IPC для AMD Zen составляет ~3,5 команды за такт. Много это? По сравнению с IPC 0,02...0,05 для процессора i8086 конечно (там CPI был, в среднем, от 20 до 50), а вот по современным меркам это уже позапрошлое поколение.
Ссылки на все 10 статей цикла «Галопом по вычислительным Европам»:
Галопом по вычислительным Европам. Часть 1. Что такое процессор.
Галопом по вычислительным Европам. Часть 2. Пути повышения IPC.
Галопом по вычислительным Европам. Часть 3. Оптимизация.
Галопом по вычислительным Европам. Часть 4. Как накормить процессор.
Галопом по вычислительным Европам. Часть 5. Память.
Галопом по вычислительным Европам. Часть 6. Спецпроцессоры.
Галопом по вычислительным Европам. Часть 7. Ввод-вывод.
Галопом по вычислительным Европам. Часть 8. Хранение данных.
Галопом по вычислительным Европам. Часть 9. Параллельные миры и техпроцессы.
Галопом по вычислительным Европам. Часть 10. Китайский путь и персональная безопасность.