Статья писалась исключительно для LIMB.cc и нигде больше не публиковалась.
Вступление
Приветствую всех читателей! В предисловии хотел бы сразу высказать своё мнение о мусоре в виде ИИ-статей на форумах - это поражает.
Сегодня я хочу погрузиться в работу процессора, посмотреть на него с точки зрения абстракций и объяснить самое важное.
Не понимая, как работает процессор, вы не сможете правильно оптимизировать свои программы. В любом случае, для качественной оптимизации нужен опыт - точнее, опыт, который позволит улучшить оптимизацию даже по сравнению с современными компиляторами высокого уровня.
Содержание
Глава 1. История
Глава 2. Центральный процессор и арифметико‑логическое устройство (АЛУ)
Глава 3. Заключение
В статье я сосредоточусь конкретно на архитектуре
В 1968 году Роберт Нойс, изобретатель кремниевой интегральной схемы, Гордон Мур, автор известного закона Мура, и Артур Рок, венчурный капиталист из Сан-Франциско, основали корпорацию
В конце 1960-х годов калькуляторы представляли собой большие электромеханические машины размером с современный лазерный принтер и весили около 20 килограммов.
В сентябре 1969 года японская компания Busicom обратилась к корпорации
В 1970 году появился первый процессор на одной микросхеме -
Когда Intel решила использовать процессор 4004 в других разработках, компания предложила Busicom продать все права на новую микросхему за 60 000 долларов, то есть ровно столько, сколько Busicom заплатила Intel за разработку. Busicom согласилась, и Intel приступила к созданию 8-разрядной версии микросхемы - Intel 8008, выпущенной в 1972 году.
Все процессоры семейства Intel, начиная с моделей 4004 и 8008, перечислены на картине ниже:
Поскольку никто не ожидал большого спроса на микросхему 8008, она была выпущена достаточно ограниченным тиражом. Ко всеобщему удивлению, новая микросхема вызвала большой интерес, поэтому компания
В 1978 году же появился процессор 8086, который стал первым 16-разрядным процессором
После этого
Однако была одна проблема которая заключалась в том, что
Чтобы решить часть этой проблемы, была введена специальная инструкция EMMS, которая обнуляла регистры стека FPU после работы с MMX.
Однако и это имело свои ограничения. Нельзя было одновременно использовать инструкции FPU и MMX в одном фрагменте кода без риска потери данных. Например, регистр
В итоге, архитектура MMX была полезной для ускорения мультимедийных операций, но накладывала ограничения на одновременное использование FPU и MMX. Программистам приходилось внимательно планировать, где применять те или иные инструкции, чтобы не потерять данные и не снизить производительность программы.
На свет появился процессор
Они добавили SSE - расширение, которое позволяло процессору одновременно обрабатывать сразу несколько чисел с плавающей точкой и мультимедиа. Расширение очень похоже на MMX, которое обсуждалось выше.
SSE - это тоже про SIMD. То есть, одна инструкция - много данных. Другими словами, вы даёте процессору одну инструкцию, а он обрабатывает сразу целую кучу чисел.
И вот, что реально подняло настроение программистам:
Я не буду подробно останавливаться на дальнейшей истории процессоров.
Наша цель - понять принципы работы CPU, а не перечислить все модели.
Глава 2. Центральный процессор и арифметико‑логическое устройство (АЛУ)
Глава номер два.
Расскажу все самое важное.
Центральный процессор - сердце любого компьютера, и чтобы понять его работу, нужно осознать, как программы превращаются в действия железа. Когда вы пишете на ассемблере, например:
В первую очередь после компиляции программы, в памяти хранится лишь обычный поток байтов, ничего более, этот поток байтов направляется прямиком в конвейер процессора. Сначала блок выборки забирает данные из кэша инструкций, ориентируясь на адрес в регистре-счетчике. На этом этапе для железа это всё еще просто сырые числа, которые нужно превратить в реальные действия.
Затем в дело вступает декодер. Задача декодера - распознать в мешанине байтов конкретные команды. Поскольку современные процессоры (x86) работают на архитектуре
После этого подготовленные микрооперации попадают в блоки исполнения (
Выше я объяснил похверностно, теперь подробнее пройдемся по каждому этапу:
Первый этап - байты программы направляются из оперативной памяти в кэш-память первого уровня, которая находится непосредственно в кристалле процессора. На этом уровне данные все еще представляют собой неструктурированную последовательность бит. Контроллер памяти постоянно подкачивает новые порции данных, чтобы конвейер не простаивал в ожидании медленной
Далее вступает в работу блок предварительной выборки или префетчер. Он анализирует поток и пытается предугадать, какие байты понадобятся дальше, чтобы заранее переместить их ближе к вычислительным ядрам. Этот механизм позволяет сгладить задержки доступа к памяти. На данном этапе поток байтов все еще выглядит как хаотичный набор чисел, и процессор не понимает их логический смысл, он просто обеспечивает физическую доставку электрических сигналов в нужные буферы.
Затем байты попадают в блок декодирования. Здесь происходит магия превращения сложных CISC-инструкций, характерных для архитектуры x86, во внутренние микрооперации процессора. Декодер определяет границы каждой инструкции, так как в современных системах они могут иметь разную длину от одного до пятнадцати байт.
Если инструкция оказывается слишком сложной для прямого декодирования, задействуется ПЗУ микрокода. Это встроенная в процессор база данных, которая содержит последовательности простейших действий для реализации тяжелых команд. Например, одна команда ассемблера может развернуться в десятки мелких микроопераций.
Микрокод позволяет аппаратному обеспечению гибко обрабатывать старые или специфические функции, по сути являясь программным слоем внутри самого железа.
После подготовки микрооперации направляются в планировщик, который распределяет их по исполнительным портам. Здесь в дело вступает внеочередное выполнение: процессор может менять порядок команд, если они не зависят друг от друга, чтобы максимально загрузить все свои блоки. Инструкции выстраиваются в очередь и ждут момента, когда необходимые для расчетов данные будут готовы и свободны соответствующие вычислительные ресурсы.
Центральным узлом, где происходит финальная трансформация данных, является АЛУ -
АЛУ работает в тесной связке с регистрами - сверхбыстрыми ячейками памяти внутри ядра. Когда микрооперация доходит до исполнения, АЛУ берет значения из указанных регистров, проводит вычисление за доли наносекунды и отправляет результат обратно. Параллельно с этим обновляется регистр флагов, который фиксирует специфические состояния, например, не получился ли в результате ноль или не произошло ли переполнение разрядной сетки. Эти флаги критически важны для ветвления программы и принятия решений о дальнейших шагах.
В завершение процесса результаты работы АЛУ и других блоков фиксируются в блоке упорядочивания. Хотя команды могли выполняться не по порядку ради скорости, в память они должны быть записаны строго в той последовательности, которая была в исходном бинарном файле. Только после этого этапа инструкция считается полностью завершенной, а состояние процессора обновляется для перехода к следующему циклу выборки, декодирования и вычисления.
Если же показать весь процесс на листинге, он выглядет так:
Глава 3. Заключение
Данная глава носит введение. В последующих главах мы разберём устройство процессора гораздо глубже: посмотрим, как на практике работает
Надеюсь, материал оказался хотя бы немного полезным. Если так, ставьте лукас.
Вступление
Приветствую всех читателей! В предисловии хотел бы сразу высказать своё мнение о мусоре в виде ИИ-статей на форумах - это поражает.
Сегодня я хочу погрузиться в работу процессора, посмотреть на него с точки зрения абстракций и объяснить самое важное.
Не понимая, как работает процессор, вы не сможете правильно оптимизировать свои программы. В любом случае, для качественной оптимизации нужен опыт - точнее, опыт, который позволит улучшить оптимизацию даже по сравнению с современными компиляторами высокого уровня.
Содержание
Глава 1. История
Глава 2. Центральный процессор и арифметико‑логическое устройство (АЛУ)
Глава 3. Заключение
Глава 1. История
В первую очередь я хотел бы погрузиться в предысторию процессоров, чтобы получить хоть какое-то понимание истории. Без знания прошлого дальнейшее движение в изучении архитектуры было бы затруднительным.В статье я сосредоточусь конкретно на архитектуре
CISC, а также на процессорах Intel и AMD. P.S и затрону RISC.В 1968 году Роберт Нойс, изобретатель кремниевой интегральной схемы, Гордон Мур, автор известного закона Мура, и Артур Рок, венчурный капиталист из Сан-Франциско, основали корпорацию
Intel для производства компьютерных микросхем. За первый год существования корпорации продажи микросхем составили всего 3000 долларов, но затем объём продаж значительно вырос. Сегодня Intel является крупнейшим мировым производителем процессоров.В конце 1960-х годов калькуляторы представляли собой большие электромеханические машины размером с современный лазерный принтер и весили около 20 килограммов.
В сентябре 1969 года японская компания Busicom обратилась к корпорации
Intel с просьбой разработать 12 нестандартных микросхем для своей электронной вычислительной машины. Инженер Intel Тед Хофф, назначенный руководителем проекта, предложил разместить 4-разрядный универсальный процессор на одной микросхеме, который выполнял бы все необходимые функции, но оказался бы проще и дешевле.В 1970 году появился первый процессор на одной микросхеме -
Intel 4004 с 2300 транзисторами. Стоит отметить, что ни сотрудники Intel, ни сотрудники Busicom не осознавали масштаба сделанного открытия.Когда Intel решила использовать процессор 4004 в других разработках, компания предложила Busicom продать все права на новую микросхему за 60 000 долларов, то есть ровно столько, сколько Busicom заплатила Intel за разработку. Busicom согласилась, и Intel приступила к созданию 8-разрядной версии микросхемы - Intel 8008, выпущенной в 1972 году.
Все процессоры семейства Intel, начиная с моделей 4004 и 8008, перечислены на картине ниже:
Не удалось прогрузить медиа
Поскольку никто не ожидал большого спроса на микросхему 8008, она была выпущена достаточно ограниченным тиражом. Ко всеобщему удивлению, новая микросхема вызвала большой интерес, поэтому компания
Intel начала разработку еще одного процессора, в котором предел в 16 Кбайт памяти (как у процессора 8008), навязываемый количеством внешних выводов микросхемы, был преодолен. Так появился небольшой универсальный процессор 8080, выпущенный в 1974 году. Как и PDP-8, он произвел революцию на компьютерном рынке и сразу стал массовым продуктом. Разница лишь в масштабах: компания DEC продала тысячи PDP-8, а Intel - миллионы процессоров 8080.В 1978 году же появился процессор 8086, который стал первым 16-разрядным процессором
Intel на одной микросхеме; он был похож на старый 8080, но не полностью совместим с ним, а чуть позже вышел 8088, у которого была та же архитектура, но 8-разрядная шина, из-за чего он работал медленнее, но стоил дешевле, и именно его выбрала компания IBM для своего первого IBM PC, что сделало 8088 стандартом для персональных компьютеров; однако оба процессора не могли работать с памятью больше 1 Мбайта, и это стало проблемой к началу 1980-х, поэтому Intel выпустила 80286, который был совместим с 8086, но с новой организацией памяти, что позволило работать с большими объёмами, хотя совместимость с прошлым делала структуру памяти немного неудобной, и этот процессор активно использовался в IBM PC/AT и PS/2, предлагая пользователям более высокую скорость по сравнению с 8088; затем появился 80386, уже 32-разрядный, который позволял выполнять старые программы, но был быстрее и более универсален, а через четыре года вышел 80486, который имел встроенный кэш 8 Кбайт, поддерживал операции с плавающей точкой, мог хранить часто используемые данные внутри процессора, чтобы не тратить много времени на медленные обращения к памяти, и поддерживал мультипроцессорные системы, что позволяло строить компьютеры с несколькими процессорами.После этого
Intel выпустила Pentium, где появилась технология MMX - которая была первым понятиям слова SIMD, она была создана для ускорения работы с мультимедиа - обработки графики, аудио и видео, что позволяло делать игры и видео быстрее, но MMX использовал те же регистры, что и обычные инструкции, из-за чего оптимизировать обычные программы было сложнее.Однако была одна проблема которая заключалась в том, что
Intel не хотела или не могла выделять новые физические регистры для технологии MMX. В результате они решили использовать уже существующие регистры математического сопроцессора FPU для MMX. Это означало, что регистры MMX и FPU были общими, и выполнение команд одного типа могло затереть данные другого.Чтобы решить часть этой проблемы, была введена специальная инструкция EMMS, которая обнуляла регистры стека FPU после работы с MMX.
Однако и это имело свои ограничения. Нельзя было одновременно использовать инструкции FPU и MMX в одном фрагменте кода без риска потери данных. Например, регистр
MMX(0)мог спокойно затереть верхушку стека FPU - st(0), что требовало особой осторожности при написании программ, особенно если нужно было выполнять одновременно математические вычисления и операции с мультимедиа. На практике нарушение выглядит так:Не удалось прогрузить медиа
В итоге, архитектура MMX была полезной для ускорения мультимедийных операций, но накладывала ограничения на одновременное использование FPU и MMX. Программистам приходилось внимательно планировать, где применять те или иные инструкции, чтобы не потерять данные и не снизить производительность программы.
Не удалось прогрузить медиа
На свет появился процессор
Pentium 3, и наконец Intel решила, что пора сделать жизнь программистов проще.Они добавили SSE - расширение, которое позволяло процессору одновременно обрабатывать сразу несколько чисел с плавающей точкой и мультимедиа. Расширение очень похоже на MMX, которое обсуждалось выше.
SSE - это тоже про SIMD. То есть, одна инструкция - много данных. Другими словами, вы даёте процессору одну инструкцию, а он обрабатывает сразу целую кучу чисел.
И вот, что реально подняло настроение программистам:
Intel додумалась наконец выделить отдельные физические регистры под SSE, так что теперь можно было спокойно использовать эти команды, не боясь, что данные старого FPU испарятся куда-то в небытие. Это было настоящим облегчением после старого MMX-квеста, где один неверный шаг мог стереть вершину стека FPU и заставить вас рыться в логике программы, как детектив на месте преступления.Не удалось прогрузить медиа
Я не буду подробно останавливаться на дальнейшей истории процессоров.
Наша цель - понять принципы работы CPU, а не перечислить все модели.
Глава 2. Центральный процессор и арифметико‑логическое устройство (АЛУ)
Глава номер два.
Расскажу все самое важное.
Центральный процессор - сердце любого компьютера, и чтобы понять его работу, нужно осознать, как программы превращаются в действия железа. Когда вы пишете на ассемблере, например:
C:
mov eax, 5
add eax, 10
Затем в дело вступает декодер. Задача декодера - распознать в мешанине байтов конкретные команды. Поскольку современные процессоры (x86) работают на архитектуре
CISC, команды могут иметь разную длину. Декодер нарезает поток на понятные куски и переводит их во внутренний язык процессора - микрооперации (uOps). Это более простые и атомарные инструкции, которые кремниевое ядро может выполнять максимально быстро.После этого подготовленные микрооперации попадают в блоки исполнения (
ALU, FPU), где происходит математика, работа с памятью или логические переходы, превращая статический байт-код в живой процесс.Выше я объяснил похверностно, теперь подробнее пройдемся по каждому этапу:
Первый этап - байты программы направляются из оперативной памяти в кэш-память первого уровня, которая находится непосредственно в кристалле процессора. На этом уровне данные все еще представляют собой неструктурированную последовательность бит. Контроллер памяти постоянно подкачивает новые порции данных, чтобы конвейер не простаивал в ожидании медленной
RAM. В этот момент процессор смотрит на указатель инструкции, который жестко определяет, с какого именно смещения в этом потоке нужно начинать чтение следующей порции кода.Далее вступает в работу блок предварительной выборки или префетчер. Он анализирует поток и пытается предугадать, какие байты понадобятся дальше, чтобы заранее переместить их ближе к вычислительным ядрам. Этот механизм позволяет сгладить задержки доступа к памяти. На данном этапе поток байтов все еще выглядит как хаотичный набор чисел, и процессор не понимает их логический смысл, он просто обеспечивает физическую доставку электрических сигналов в нужные буферы.
Затем байты попадают в блок декодирования. Здесь происходит магия превращения сложных CISC-инструкций, характерных для архитектуры x86, во внутренние микрооперации процессора. Декодер определяет границы каждой инструкции, так как в современных системах они могут иметь разную длину от одного до пятнадцати байт.
Если инструкция оказывается слишком сложной для прямого декодирования, задействуется ПЗУ микрокода. Это встроенная в процессор база данных, которая содержит последовательности простейших действий для реализации тяжелых команд. Например, одна команда ассемблера может развернуться в десятки мелких микроопераций.
Микрокод позволяет аппаратному обеспечению гибко обрабатывать старые или специфические функции, по сути являясь программным слоем внутри самого железа.
После подготовки микрооперации направляются в планировщик, который распределяет их по исполнительным портам. Здесь в дело вступает внеочередное выполнение: процессор может менять порядок команд, если они не зависят друг от друга, чтобы максимально загрузить все свои блоки. Инструкции выстраиваются в очередь и ждут момента, когда необходимые для расчетов данные будут готовы и свободны соответствующие вычислительные ресурсы.
Центральным узлом, где происходит финальная трансформация данных, является АЛУ -
арифметико-логическое устройство. А кстати, хотелось бы еще про АЛУ рассказать - это фундаментальный блок процессора, который выполняет базовые математические действия вроде сложения и вычитания, а также логические операции типа И, ИЛИ или исключающее ИЛИ. По сути, это набор транзисторных схем, которые принимают на вход два числа в двоичном виде и на основе кода операции выдают результат. Без АЛУ невозможна никакая обработка информации, так как любое действие программы в конечном счете сводится к математике.АЛУ работает в тесной связке с регистрами - сверхбыстрыми ячейками памяти внутри ядра. Когда микрооперация доходит до исполнения, АЛУ берет значения из указанных регистров, проводит вычисление за доли наносекунды и отправляет результат обратно. Параллельно с этим обновляется регистр флагов, который фиксирует специфические состояния, например, не получился ли в результате ноль или не произошло ли переполнение разрядной сетки. Эти флаги критически важны для ветвления программы и принятия решений о дальнейших шагах.
В завершение процесса результаты работы АЛУ и других блоков фиксируются в блоке упорядочивания. Хотя команды могли выполняться не по порядку ради скорости, в память они должны быть записаны строго в той последовательности, которая была в исходном бинарном файле. Только после этого этапа инструкция считается полностью завершенной, а состояние процессора обновляется для перехода к следующему циклу выборки, декодирования и вычисления.
Если же показать весь процесс на листинге, он выглядет так:
Не удалось прогрузить медиа
Глава 3. Заключение
Данная глава носит введение. В последующих главах мы разберём устройство процессора гораздо глубже: посмотрим, как на практике работает
SIMD на ассемблере, разберём реальные примеры и попробуем написать собственные функции, заменяющие стандартные из msvcrt.Надеюсь, материал оказался хотя бы немного полезным. Если так, ставьте лукас.
👍13
🔥3
🤔2
💯4
LIMB