Как проектируют процессоры
Completing the CAPTCHA proves you are a human and gives you temporary access to the web property.
What can I do to prevent this in the future?
If you are on a personal connection, like at home, you can run an anti-virus scan on your device to make sure it is not infected with malware.
If you are at an office or shared network, you can ask the network administrator to run a scan across the network looking for misconfigured or infected devices.
Another way to prevent getting this page in the future is to use Privacy Pass. You may need to download version 2.0 now from the Chrome Web Store.
Cloudflare Ray ID: 71acbe2b2873912e • Your IP : 82.102.23.104 • Performance & security by Cloudflare
Как на самом деле производят процессоры
Чтобы создать сверхмощный процессор, достаточно простого.
Песок. В наших компьютерах в буквальном смысле песок, вернее — составляющий его кремний. Это основной элемент, благодаря которому в компьютерах всё работает. А вот как из песка получаются компьютеры.
Что такое процессор
Процессор — это небольшой чип внутри вашего компьютера или телефона, который производит все вычисления. Об основе вычислений мы уже писали — это транзисторы, которые собраны в сумматоры и другие функциональные блоки.
Если очень упрощённо — это сложная система кранов и труб, только вместо воды по ним течёт ток. Если правильным образом соединить эти трубы и краны, ток будет течь полезным для человека образом и получатся вычисления: сначала суммы, потом из сумм можно получить более сложные математические операции, потом числами можно закодировать текст, цвет, пиксели, графику, звук, 3D, игры, нейросети и что угодно ещё.
Кремний
Почти все процессоры, которые производятся в мире, делаются на кремниевой основе. Это связано с тем, что у кремния подходящая внутренняя атомная структура, которая позволяет делать микросхемы и процессоры практически любой конфигурации.
Самый доступный источник кремния — песок. Но кремний, который получается из песка, на самом первом этапе недостаточно чистый: в нём есть 0,5% примесей. Может показаться, что чистота 99,5% — это круто, но для процессоров нужна чистота уровня 99,9999999%. Такой кремний называется электронным, и его можно получить после цепочки определённых химических реакций.
Когда цепочка заканчивается и остаётся только чистый кремний, можно начинать выращивать кристалл.
Кристалл и подложка
Кристаллы — это такие твёрдые тела, в которых атомы и молекулы вещества находятся в строгом порядке. Проще говоря, атомы в кристалле расположены предсказуемым образом в любой точке. Это позволяет точно понимать, как будет вести себя это вещество при любом воздействии на него. Именно это свойство кристаллической решётки используют на производстве процессоров.
Самые распространённые кристаллы — соль, драгоценные камни, лёд и графит в карандаше.
Большой кристалл можно получить, если кремний расплавить, а затем опустить туда заранее подготовленный маленький кристалл. Он сформирует вокруг себя новый слой кристаллической решётки, получившийся слой сделает то же самое, и в результате мы получим один большой кристалл. На производстве он весит под сотню килограмм, но при этом очень хрупкий.
Готовый кристалл кремния.
После того, как кристалл готов, его нарезают специальной пилой на диски толщиной в миллиметр. При этом диаметр такого диска получается около 30 сантиметров — на нём будет создаваться сразу несколько десятков процессоров.
Каждую такую пластинку тщательно шлифуют, чтобы поверхность получилась идеально ровной. Если будут зазубрины или шероховатости, то на следующих этапах диск забракуют.
Готовые отполированные пластины кремния.
Печатаем транзисторы
Когда диски отполированы, на них можно формировать процессоры. Процесс очень похож на то, как раньше печатали чёрно-белые фотографии: брали плёнку, светили сверху лампой, а снизу клали фотобумагу. Там, куда попадал свет, бумага становилось тёмной, а те места, которые закрыло чёрное изображение на плёнке, оставались белыми.
С транзисторами всё то же самое: на диск наносят специальный слой, который при попадании света реагирует с молекулами диска и изменяет его свойства. После такого облучения в этих местах диск начинает проводить ток чуть иначе — сильнее или слабее.
Чтобы так поменять только нужные участки, на пути света помещают фильтр — прямо как плёнку в фотопечати, — который закрывает те места, где менять ничего не надо.
Потом получившийся слой покрывают тонким слоем диэлектрика — это вещество, которое не проводит ток, типа изоленты. Это нужно, чтобы слои процессора не взаимодействовали друг с другом. Процесс повторяется несколько десятков раз. В результате получаются миллионы мельчайших транзисторов, которые теперь нужно соединить между собой.
Соединяем всё вместе
То, как соединяются между собой транзисторы в процессоре, называется процессорной архитектурой. У каждого поколения и модификации процессоров своя архитектура. Все производители держат в секрете тонкости архитектуры, потому что от этого может зависеть скорость работы или стоимость производства.
Так как транзисторов много, а связей между ними нужно сделать немало, то поступают так: наносят токопроводящий слой, ставят фильтр и закрепляют проводники в нужном месте. Потом слой диэлектрика и снова токопроводящий слой. В результате выходит бутерброд из проводников, которые друг другу не мешают, а транзисторы получают нужные соединения.
Токопроводящие дорожки крупным планом. На фото они уже в несколько слоёв и не мешают друг другу.
В чём сложность
Современные процессоры производятся на нанометровом уровне, то есть размеры элементов измеряются нанометрами, это очень мало.
Если, например, во время печати очень толстый мальчик упадёт на пол в соседнем цехе, еле заметная ударная волна прокатится по перекрытиям завода и печатная форма немного сдвинется, а напечатанные таким образом транзисторы окажутся бракованными. Пылинка, попавшая на пластину во время печати — это, считай, загубленное ядро процессора.
Поэтому на заводах, где делают процессоры, соблюдаются жёсткие стандарты чистоты, все ходят в масках и костюмах, на всех воздуховодах стоят фильтры, а сами заводы находятся на сейсмических подушках, чтобы толчки земной коры не мешали производить процессоры.
Крышка и упаковка
Когда дорожки готовы, диск отправляют на тесты. Там смотрят на то, как работает каждый процессор, как он греется и сколько ему нужно энергии, заодно проверяют на брак.
В зависимости от результатов процессоры с одной пластины могут получить разную маркировку и продаваться по разной стоимости. Те процессоры, которые получились более удачными, становятся дорогими серверными продуктами. Те, где кто-то рядом чихнул или вздохнул, имеют некоторые несовершенства и дефекты, их могут отправить на потребительскую линию.
После тестов диск разрезают на готовые процессорные ядра.
Пластина со множеством одинаковых процессорных ядер.
Робот вырезает ядра из готовой пластины.
После этого к ядру процессора добавляют контакты, чтобы можно было вставить его в материнскую плату, и накрывают крышкой. Чёрный или металлический прямоугольник, из которого торчат ножки, — это как раз крышка.
Крышка выполняет две функции: защищает сам кристалл от повреждений и отводит от него тепло во время работы. Дело в том, что миллионы транзисторов при работе нагреваются, и если процессор не остужать, то он перегреется и кристалл может испортиться. Чтобы такого не произошло, на крышку процессора ставят воздушные кулеры или делают водяное охлаждение.
Система на чипе
Чипы процессоров уже настолько маленькие, что под одной крышкой можно поместить какое-нибудь ещё устройство. Например, видеосистему — то, что обсчитывает картинку перед выводом на экран. Или устройство радиосвязи с антенной.
В какой-то момент на маленьком чипе площадью около 1 см 2 уже можно было поместить процессор, видео, модем и блютус, сделать всё нужное для поддержки памяти и периферии — в общем, система на чипе. Подключаете к этому хозяйству экран, нужное количество антенн, портов и кнопок, а главное — здоровенную батарею, и у вас готовый смартфон. По сути, все «мозги» вашего смартфона находятся на одном маленьком чипе, а 80% пространства за экраном занимает батарея.
Дизайн простого 32 битного RISC ЦПУ и бэкенд LLVM компилятора. Проектирование процессоров и компиляторов.
В этой главе рассматриваются соответствующие концепции и идеи, касающиеся архитектуры ЦП (центральный процессор) и компилятора.
2.1 Дизайн процессора
Две известные методологии проектирования ЦП с сокращенным набором команд компьютера (RISC) и компьютер с полным набором команд (CISC). Хотя не существует определенного стандарта для разделения определенных архитектур ЦП на эти две категории, обычно большинство архитектур легко классифицируются в одну или в другую сторону в зависимости от их определяющих характеристик.
Одним из ключевых показателей того, что архитектура принадлежит к RISC или CISC, является количество инструкций ЦП, наряду со сложностью инструкций. Архитектуры RISC известны тем, что имеют относительно небольшое количество инструкций, которые обычно выполняют только одну или две операции в одном такте цикла. Однако архитектуры CISC известны тем, что имеют большое количество инструкций, которые обычно выполняют несколько сложных операций за несколько тактов [1]. Например, набор команд ARM содержит около 50 инструкций [2]. В то время как набор команд Intel x86-64 содержит более 600 инструкций [3]. Этот простой контраст подчеркивает основные цели проектирования двух категорий процессоров; RISC архитектуры, как правило, направлены на более низкую сложность в архитектуре и аппаратном дизайне, чтобы сместить сложность в сторону программного обеспечения, и CISC архитектуры стремятся сохранить большую часть сложности в аппаратном обеспечении с целью упрощения реализации программного обеспечения. В то время как это может показаться полезным переход в сторону сложности аппаратного обеспечения, это также вызывает аппаратную проверку, чтобы увеличить сложность. Это может привести к ошибкам в аппаратном дизайне, которые гораздо сложнее исправить по сравнению с ошибками, найденными в программном обеспечении [4].
Некоторые из других показателей RISC или CISC – это количество режимов адресации и формат самих слов инструкции. В целом, использование меньшего количества режимов адресации наряду с последовательным форматом инструкций приводит к более быстрой и менее сложной логике управляющего сигналом [5]. Кроме того, исследование в [6] показывает, что только в логике вычисления адресов может быть до 4× кратного увеличение структурной сложности для процессоров CISC по сравнению с RISC. Обоснование выбора конструкции процессора меняются на протяжении последних нескольких десятилетий. Раньше сложность аппаратного обеспечения, площадь микросхемы и количество транзисторов были одними из основных соображений проектирования. В последние годы, однако, фокус переключился к уменьшению потребляемой электроэнергии и мощности при увеличении скорости. Исследования в [7] установили, что существует аналогичное общую производительность сопоставимы между RISC и архитектуры CISC, хотя CISC – процессоры, как правило, требуют больше энергии.
Есть много вариантов дизайна, участвующих в разработке процессора, направленных исключительно на производительность оборудования. Однако для программного обеспечения, чтобы работать на ЦП есть дополнительные соображения, которые должны быть сделаны. Некоторые из этих соображений включают количество классов регистра, какие типы режимов адресации реализовать, и расположение области памяти.
2.2 Проектирование компилятора
В своем простейшем определении компилятор принимает программу, написанную на каком-либо исходном языке, а затем переводит ее в программу с эквивалентной функциональностью на машинный язык (язык процессора) [8]. Хотя существуют различные варианты процесса компиляции (например, интерпретаторы и компиляторы justin-time (JIT)), в этой статье основное внимание уделяется стандартным компиляторам, в частности тем, которые могут принимать входные программы, написанные на языке C, а затем выводить либо код сборки или машины целевой архитектуры. Рассматривая C в качестве исходного языка, два набора компиляторов действительно считают достаточно зрелыми и оптимизированным для решения современных проблем с программным обеспечением: GCC (Коллекция компиляторов GNU) и LLVM. Несмотря на схожесть функций конечных пользователей, GCC и LLVM работают по-разному друг от друга как в архитектуре программного обеспечения, так и в философии организаций.
2.2.1 Двоичный интерфейс приложения
Перед рассмотрением компилятора для целевого объекта должен быть определен двоичный интерфейс приложения (ABI). Это охватывает все подробности о том, как код и данные взаимодействуют с оборудованием процессора. Некоторые из важных вариантов проектирования, которые должны быть сделаны, включают выравнивание различных типов данных в памяти, определение классов регистров (какие регистры могут хранить, какие типы данных) и соглашения о вызовах функций (независимо от того, помещаются ли операнды функций в стек, в регистры или комбинацию обоих) [9]. ABI должен тщательно рассмотреть архитектуру ЦП, чтобы быть уверенным, что каждый из вариантов дизайна физически возможен, и что они эффективно используют аппаратное обеспечение ЦП при наличии нескольких решений проблемы.

2.2.2 Модели компилятора
Современные компиляторы обычно работают в трех основных фазах: фронтенд, оптимизатор, и бэкенд. Два подхода, как компиляторы должны выполнить эту задачу, являются подход Ахо-Ульмана [8] и подход Дэвидсона-Фрейзера [10]. Блок схемы для каждой из этих моделей показаны на рис. 2.1 и рис. 2.2. Хотя функции эти между собой, эти модели имеют существенные отличия в том, как они выполняют процесс оптимизации и генерации кода.
Модель Ахо-Ульмана уделяет большое внимание использованию целевого языка промежуточного представления (intermediate representation – IR) для основной части оптимизации перед бэкенд частью, что позволяет процессу выбора инструкций использовать подход, основанный на затратах. Модель Дэвидсона Фрейзера направлена на преобразование IR в целевой независимый тип “регистр языка перевода” (язык перевода (RTL) не следует путать с абстракцией дизайна уровня передачи регистров (RTL), используемой для проектирования цифровой логики). RTL затем проходит процесс расширения с последующим распознавателем, который выбирает инструкции на основе расширенного представления [9]. Данная статья посвящена модели Ахо Ульмани, как инструмент LLVM сконструирован с использованием этой методики.
На каждом этапе модели Ахо Ульмана компилятор осуществляет перевод исходной программы в разные представления, которые приносит программа, делая этот этап более близкая к машинному (целевому) языку. Существует существенные преимущества у компилятора разработанного с использованием этой модели; из-за модульности и определенных границ каждого этапа, новые исходные языки, целевые архитектуры и этапы оптимизации могут быть добавлены или изменены в основном независимо друг от друга. Для нового исходного языка нужно только продумать дизайн фронтенда, такой который на выходе соответствует IR, оптимизацию проходит в основном язык-агностик, так, что пока язык работают только на IR и сохраняет функции программы, и, наконец, генерация кода для новой целевой архитектуры только требует разработки бэкенд части, которая принимает IR и формирует выходной машинный код (как правило в сборке или в качестве машинного кода).
2.2.3 GCC
GCC был впервые выпущен в 1984 году Ричардом Столманом [11]. GCC полностью написана на C и в настоящее время по-прежнему поддерживает большую часть той же архитектуры программного обеспечения, которая существовала в первоначальном выпуске более 30 лет назад. Независимо от этого факта, почти каждый стандартный ЦП имеет порт GCC, ЦП в состоянии использовать данный порт. Даже архитектуры, которые не имеют бэкенд части в исходном дереве GCC, как правило, имеют либо частный выпуск, либо пользовательскую сборку, поддерживаемую третьей стороной; примером одной такой архитектуры является Texas Instruments MSP430 [12]. Хотя GCC является популярным вариантом компилятора, этот документ фокусируется на LLVM вместо GCC, так как LLVM обладает значительно более современной кодовой базой.
2.2.4 Код LLVM
LLVM был первоначально выпущен в 2003 году, исполнитель Chris Lattner [13] – это был дипломный проект на звание магистра. С тех пор компилятор чрезвычайно вырос в полностью полную и открытую инфраструктуру компилятора. Написанный на C++ и охватывающий его объектно – ориентированный характер программирования, LLVM теперь стал богатым набором инструментов и библиотек на основе компиляторов. В то время как LLVM раньше был аббревиатурой “низкоуровневой виртуальной машины”, представляющей ее богатый, виртуальный набор инструкций IR язык, проект вырос, чтобы охватить больший объем проектов и целей и LLVM больше не означает ничего [14]. Существует гораздо меньше архитектур, которые поддерживаются в LLVM по сравнению с GCC, потому что LLVM достаточно нов. Несмотря на это, все еще есть организации, которые предпочитают использовать LLVM в качестве инструмента компилятора по умолчанию над GCC [15, 16]. Оставшаяся часть этого раздела описывает три основных этапа компилятора LLVM.
2.2.4.1 Фронтенд
Отвечает за перевод программы ввода из текста, написанного человеком. Этот этап осуществляется посредством лексического, синтаксического и семантического анализа. Формат вывода фронтенда является IR-код инфраструктуры LLVM, IR – это полностью полный набор виртуальных команд, который имеет операции, подобные архитектурам RISC; однако он полностью типизирован, использует представление статического одиночного назначения (SSA) и имеет неограниченное количество виртуальных регистров. Он достаточно низок, так что его можно легко связать с аппаратными операциями, но он также включает в себя достаточно высокоуровневый поток управления и информацию о данных, чтобы обеспечить сложный анализ и оптимизацию [17]. Все из этих характеристик IR LLVM прибавляет на очень эффективный, машино-независимый оптимизатор.
2.2.4.2 Оптимизация
Оптимизатор отвечает за перевод IR с выходных данных фронтенда в эквивалентную, но оптимизированную программу в IR. Хотя на этом этапе выполняется основная часть оптимизаций; оптимизация может и должна быть завершена на каждом этапе компиляции. Пользователи могут оптимизировать код при его написании до того, как он достигнет фронтенда, а бэкенд может оптимизировать код специально для целевой архитектуры и оборудования.
В целом, есть две основные цели этапа оптимизации: увеличить скорость выполнения целевой программы и уменьшить размер кода целевой программы. Для достижения этих целей оптимизации обычно выполняются в несколько проходов по IR, где каждый проход имеет конкретную цель меньшей области. Один из простых способов организации IR, чтобы помочь в оптимизации через форму SSA. Эта форма гарантирует, что каждая переменная определяется ровно один раз, что упрощает многие оптимизации, такие как устранение мертвого кода, устранение ребер, построение цикла и многое другое [13].
2.2.4.3 Бэкенд
Бэкенд отвечает за перевод программы из IR в машинный код (обычно код сборки или машины). По этой причине этот этап также обычно называют генератором кода. Наиболее сложные задачи, которые решаются на этом этапе – это выбор инструкций и распределение регистров.
Выбор инструкций отвечает за преобразование операций, указанных IR, в инструкции, доступные в целевой архитектуре. Для простого примера, рассмотрим программу, в IR, содержащий логическую операцию NOT. Если целевая архитектура не имеет логического NOT инструкции, но она содержит логическую XOR функцию, селектор инструкций будет нести ответственность за преобразования “NOT” операцию в операцию “XOR – 1”, так как они функционально эквивалентны.
Распределение регистров – это совершенно другая проблема, поскольку IR использует неограниченное количество переменных, а не фиксированное количество регистров. Распределитель регистров назначает переменные в IR регистрам в целевой архитектуре. Компилятору требуется информация обо всех регистрах специального назначения вместе с различными классами регистров, которые могут существовать в целевом объекте. На этом этапе решаются также другие вопросы, такие как упорядочение инструкций, выделение памяти и разрешение относительных адресов. Как только все эти проблемы решены, серверная часть может выдать окончательный целевой код сборки или машинный код.