Как разрабатываются и создаются процессоры часть 3
Существует общественное мнение, что процессор - мозг компьютера. Но как работает этот самый мозг, состоящий из миллиардов транзисторов? В этой небольшой серии статей (всего из четырех частей), портал Techspot решил тщательно разобраться в том, что же заставляет работать ваше "железо".
В статьях будут затронуты такие темы, как принцип работы компьютерной архитектуры, дизайн микросхем процессоров, сверхбольшая масштабная интеграция (VLSI), создание чипов и грядущие тренды. Если вам всегда было интересно, как работают процессоры, то присаживайтесь прямо сейчас и наслаждайтесь чтением, потому что именно с этого и начинается эта статья.
Для начала, нужно понять из чего состоит процессор и как блоки соединяются в функциональное целое. Также будет затронута тема ядер процессоров, иерархии памяти, прогнозирования ветвлений и многого другого. Для начала, стоит дать базовое определение тому, что именно делает процессор. Если говорить простым языком, то процессор проводит операции над введенными командами, следуя конкретным инструкциям. Такой операцией может быть считывание значений из памяти, сложение этих значений а затем сохранение их в другом отделе памяти. Или что-то более сложное, например - деление двух чисел, если результат предыдущего вычисления оказался выше нуля.
Любая программа, будь то операционная система или видеоигра, представляет собой набор инструкций, которые необходимо выполнить. Эти действия загружаются из памяти и запускаются по очереди, вплоть до окончания программы. Многие разработчики пишут программы на сложных языках программирования, например, C++ или Python, но стоит отметить, что процессор их попросту не понимает. Все, что он может - обработать нули и единицы, поэтому необходимо представить код в подобном формате.
Программы представляют собой набор низкоуровневых инструкций. Их называют языком ассемблера (assembly language) и они являются одной из частей архитектуры набора команд (ISA). Процессоры запрограммированы на распознавание и выполнение этих инструкций. Самыми распространенными архитектурами набора команд являются x86, MIPS, ARM, RISC-V и PowerPC. Каждая из них отличается друг от друга написанием кода, по аналогии с языками программирования.
Эти архитектуры можно разбить на две категории: архитектуры с фиксированной длиной и переменной длиной. RISC-V является архитектурой с фиксированной длиной, и это означает, что по количеству битов можно понять можно определить тип инструкции. Ее полная противоположность - это x86, архитектура с переменной длиной, в которой каждая инструкция может быть закодирована совершенно по-разному и с разным количеством битов в каждой части. Именно поэтому декодер инструкций на процессорах с архитектурой x86 является самой сложной деталью всего устройства.
Инструкции с фиксированной длиной декодируются легче и быстрее, но у таких архитектур существует лимит поддерживаемых инструкций. Так, самые распространенные процессоры на RISC-V с открытым доступом поддерживают около 100 инструкций, а x86 является закрытой архитектурой, поэтому никто не знает точного количества поддерживаемых инструкций. Многие считают, что это число достигает нескольких тысяч, но это лишь догадки. Тем не менее, несмотря на такую разницу, процессоры на обеих архитектурах выполняют одни и те же функции.
Примеры инструкций архитектуры RISC-V. Инструкция opcode справа занимает 7 бит, что, в свою очередь, определяет ее тип. Каждая инструкция состоит из битов, которые отвечают за то, какие регистры и функции будут выполняться. Так инструкции ассемблера превращаются в бинарный код, который процессор способен считывать.
Итак, теперь можно включить компьютер и запускать программы. Стоит отметить, что выполнение инструкции состоит из нескольких базовых шагов.
Первым таким шагом является перенос инструкции из памяти в сам процессор. На второй стадии инструкция декодируется, чтобы процессор смог понять, что это за инструкция. Типов инструкций много - от арифметических действий до инструкций памяти. После того, как процессор определил тип инструкции, он достает необходимые операнды из памяти или внутренних регистров. Объясняется это просто - вы не можете сложить числа A и B, если не знаете их значений. Стоит также упомянуть, что, так как многие современные процессоры - 64-битные, то размер значения данных тоже будет составлять 64 бита.
64 бита - это пропускная способность регистра процессора; пути данных и/или адреса памяти. Чем больше бит, тем больше информации компьютер может обрабатывать за раз. Проще говоря, 64-битный процессор может обрабатывать в два раза больше информации, чем 32-битный.
После того, как процессор получил необходимые операнды, начинается выполнение инструкции и операций над введенными данными. Это может быть добавление чисел, проведение логических манипуляций или даже отсутствие действий, когда значение просто отправляется дальше. После подсчета результата, процессор может снова обратиться к памяти, чтобы сохранить полученное значение там или же просто отложить полученное значение в одном из внутренних регистров. Только после того, как результат сохранен, процессор обновит состояние различных элементов и перейдет к выполнению следующей инструкции.
Следует отметить, что вся вышеперечисленная цепочка действий значительно упрощена, поскольку в реальных ситуациях большинство современных процессоров разделяют все эти действия на 20+ более мелких циклов, чтобы повысить эффективность. В профессиональной среде подобное называется пайплайном - чем-то вроде трубопровода, который постепенно заполняется жидкостью, но как только заполнится полностью - внутри создается постоянный поток.
Пример четырехступенчатого пайплайна. Цветные квадраты представляют собой независимые друг от друга инструкции.
Прохождение циклов - тщательно отлаженный процесс, но не все инструкции заканчиваются одновременно. Сложение, например, выполняется невероятно быстро, а вот делению или загрузке из памяти может потребоваться на выполнение несколько сотен циклов. Современные процессоры, вместо того, чтобы простаивать в ожидании завершения одной медленной инструкции, могут выполнять инструкции вне очереди. Процессор сам способен определить, какую инструкцию лучше выполнить в данный момент, а какие - после нее. Если выполняемая инструкция еще не готова, то система может забежать немного вперед, чтобы посмотреть, готово ли что-то другое.
Современные процессоры, кроме внеочередного выполнения инструкций, обладают также суперскалярной архитектурой. Это означает, что процессор может выполнять сразу несколько инструкций на каждом из этапов пайплайна. Для того, чтобы это было возможно, процессору необходимо иметь несколько копий каждого этапа пайплайна. Таким образом, если процессор видит две доступные для исполнения инструкции, между которыми нет никакой зависимости друг от друга, то он сможет одновременно выполнить обе. Такая технология называется одновременной многопотоковостью (SMT), более известной как гиперпотоковость (Hyper-Threading). Процессоры Intel и AMD поддерживают двухстороннюю одновременную многопотоковость, в то время как IBM разработала чипы, поддерживающие уже восьмистороннюю многопотоковость.
Для того, чтобы в точности прорабатывать подобную схему, процессору, помимо ядра, для работы необходимы и другие элементы. В каждом процессоре расположены сотни модулей, причем каждый предназначен для специфической задачи, но в этой статье будут затронуты лишь самые важные. Основные два - это кэш и блок предсказания ветвлений.
Неопытных пользователей кэш может сбить с толку, ведь его главная задача - хранить данные, прямо как оперативная память или любой другой накопитель. Главное отличие кэша заключается в его огромной скорости и низкой задержке при работе с данными. Несмотря на то, что оперативная память обладает высокой скоростью работы с данными, она все еще в разы медленней кэша и слишком медленная для работы процессора. Если говорить, о более точных цифрах, то кэш быстрее оперативной памяти в 100 раз и в 1000 раз быстрее любого SSD. Без кэша процессоры работали бы в разы медленней.
Почти в каждом процессоре есть три уровня кэша - это называется иерархией памяти. Кэш 1 уровня (L1) - самый быстрый и самый маленький, 3 уровня (L3) - наоборот, крупнейший и медленный, а кэш 2 уровня (L2) - "золотая середина" между ними. Выше кэша в иерархии памяти стоят маленькие регистры, в которых сохраняется одиночное значение данных во время работы процессора. Эти регистры по скорости даже опережают кэш. Регистры используются, когда компилятор переводит высокоуровневые программы в язык ассемблера.
Когда процессор запрашивает данные из памяти, то он сначала проверяет, находятся ли эти данные в кэше первого уровня. Если они там есть, то процессор получает доступ к ним всего за пару циклов. Однако, если данных нет в кэше первого уровня, то процессор поищет их в кэше второго, а затем третьего уровня. С каждым уровнем будет снижаться скорость и увеличиваться задержка. Наконец, если в кэше данных не было, процессор начнет искать их уже в основной памяти (RAM).
В большинстве процессоров каждое ядро оснащено двумя кэшами первого уровня - один предназначен для данных, а другой - для инструкций. Кэш первого уровня, зачастую, около 100 КБ в размере, хотя это число может отличаться в зависимости от процессора. Обычно на каждое ядро приходится по кэшу второго уровня, хотя в некоторых архитектурах процессоров может кэш может быть разделен между двумя ядрами. Размер этого кэша составляет уже несколько сотен килобайт. Самым большим (несколько десятков мегабайт) является кэш 3 уровня, который делится сразу между всеми ядрами процессора.
Во время обработки кода процессором, инструкции и значения данных в большинстве случаев направляются в кэш. Так значительно увеличивается скорость выполнения задачи, поскольку процессору не нужно обращаться к главной памяти. Более подробно работа систем памяти будет рассмотрена во второй и третьей части этой серии статей.
Вторым важнейшим элементом процессора является блок предсказания ветвлений. Разветвленные инструкции являются чем-то вроде команды “если”, только в контексте процессора. Одна часть инструкций будет выполняться, если условие верно, а другая - если условие ложно. Пример: необходимо сравнить два числа и, если числа равны, то выполнить одну функцию, а если нет - то другую. Ветвления довольно распространены и, зачастую, составляют около 20% всех инструкций программы.
На бумаге разветвленные инструкции звучат довольно просто, но для процессоров их выполнение может быть довольно проблематичным. Поскольку процессор может выполнять 10-20 инструкций одновременно, ему важно понимать, какие именно нужно обработать. Процессору может понадобиться 5 циклов, чтобы определить является ли инструкция разветвленной, а затем до 10 циклов для того, чтобы определить верна она или нет. В это же время, процессор может начать выполнять десятки дополнительных инструкций, даже не зная правильно ли их выполнение.
Для решения этой проблемы все современные высокопроизводительные процессоры используют технологию спекулятивного выполнения. Благодаря этой технологии процессор запоминает выполняемые разветвленные инструкции и автоматически угадывает, произойдет ли ветвление или нет. Если системе удалось угадать, то процессор будет заранее выполнять другие инструкции, что увеличивает производительность. Если же не удалось, то процессор остановит выполнение всех неподходящих инструкций и начнет выполнять задачи с правильной точки.
Блоки предсказания ветвлений - это нечто вроде ранней формы машинного обучения, поскольку блок будет постепенно заучивать принцип работы разветвленных инструкций. Благодаря тому, что блоки развивались и улучшались десятилетиями, точность прогнозов в современных процессорах превышает 90%.
Несмотря на то, что эти предсказания могут увеличить производительность процессора, они также образуют дыры в безопасности. Так, недавняя уязвимость Spectre позволяла злоумышленникам получить доступ к процессору именно через блок предсказания ветвлений. Из-за этого производители процессоров вынуждены были переписать алгоритмы работы, тем самым слегка снизив производительность.
В последние несколько десятилетий процессоры развились до невероятных высот. Благодаря умелому использованию многих элементов процессоров, производителям удалось поднять производительность на новый уровень. Увы, но эти самые производители держат все принципы работы своих технологий в строжайшем секрете, поэтому трудно понять, как работают мельчайшие детали. К счастью, большинство фундаментальных основ работы процессоров остаются неизменными, стандартизированным и общеизвестными. Если Intel вдруг внезапно решит каким-то волшебным образом увеличить скорость работы кэша, либо AMD добавит более продвинутый блок предсказания ветвлений, знайте - обе компании стараются добиться одной и той же цели.
На этом заканчивается небольшая экскурсия в мир основ работы процессоров. В следующей статье речь пойдет о том, как создаются различные компоненты процессора, о логических вентилях, частоте, энергопотреблении, печатных схемах и многом другом.
Теперь, когда мы знаем, как работают процессоры на высоком уровне, пришло время заглянуть внутрь процессора, чтобы понять, как устроены его внутренние компоненты. Эта статья является второй частью нашей серии, посвященной устройству процессоров. Если вы не читали первую часть, советуем ознакомиться с ней прежде, чем вы начнете читать дальше, поскольку в этой статье мы будем использовать понятия, освещенные ранее.
Как вы, вероятно, знаете, процессоры и большинство других современных цифровых технологий основаны на транзисторах. Самый простой способ представить транзистор – это управляемый переключатель с тремя контактами. Когда затвор включен, ток пропускается через транзистор. А когда выключен, транзистор ток не проводит. Точно так же, как и выключатель света на вашей стене, только транзистор гораздо меньше, гораздо быстрее и может управляться электрически.
В современных процессорах используются два основных типа транзисторов: pMOS и nMOS. Транзистор nMOS позволяет току течь, когда подается ненулевое напряжение на затвор, а транзистор pMOS – наоборот, проводит ток, когда напряжение на затворе стремится к нулю. Комбинируя эти типы транзисторов, мы можем создать логические вентили CMOS. В третьей части серии мы ещё остановимся подробней на физике работы процессоров.
Логический вентиль (логический элемент, гейт) – это простейшее устройство, которое принимает входной сигнал, выполняет некоторые операции и выводит результат в виде выходного сигнала. Например, вентиль AND (И) включит свой выход тогда и только тогда, когда все входы в вентиль включены. Инвертор или вентиль отрицания NOT (НЕ) включит свой выход, если вход отключен. Объединив эти два гейта, мы получим логический элемент NAND (И-НЕ), который включает свой выход, если и только если ни один из входов не включен. К другим логическим гейтам, с иной логической функциональностью, относятся OR (ИЛИ), NOR (ИЛИ-НЕ), XOR (Исключающее ИЛИ) и XNOR (Исключающее ИЛИ с инверсией).
Ниже показаны схемы двух основных логических элементов, реализованных с помощью транзисторов: вентиль отрицания (инвертор) и вентиль NAND (И-НЕ). В инверторе сверху находится транзистор pMOS, подключенный к питанию, а снизу транзистор nMOS, подключенный к земле. Транзисторы pMOS обозначаются с небольшим кружочком на затворе. Поскольку устройства pMOS срабатывают при отключенном входе, а устройства nMOS наоборот – при включенном, то несложно понять, что сигнал на выходе всегда будет противоположным сигналу на входе. Глядя на вентиль NAND, мы видим, что для него требуются четыре транзистора и что выход будет включен, пока хотя бы один из входов отключен. По такому же принципу, как формируются приведенные примеры элементарных транзисторных схем, проектируются и более сложные логические гейты и прочие схемы внутри процессоров.
Трудно представить, как из таких простейших кирпичиков – логических элементов – может получиться функционирующий компьютер. Сперва из нескольких отдельных вентилей создаётся простейшее устройство, способное выполнять какую-то простую функцию. Затем из нескольких таких простых устройств создаётся более сложное, выполняющее более сложную задачу. Процесс объединения отдельных компонентов для получения требуемой функциональности – это именно то, что применяется сегодня при создании чипов. Современные чипы имеют миллиарды транзисторов.
Вывод Суммы (Sum) включается, если A или B включены (но не оба сразу), либо если есть сигнал переноса (Cin), при этом A и B одновременно включены или выключены. Вывод переноса (Carry out) функционирует несколько сложнее – он срабатывает либо при одновременном включении A и B, либо если есть сигнал переноса и один из A или B (но не оба сразу). Чтобы соединить несколько однобитных сумматоров в один более широкий, нам попросту нужно последовательно соединить вывод переноса предыдущего бита с входом переноса текущего бита. Чем сложнее схемы, тем сложнее логика, но это самый простой способ сложить два числа. Современные процессоры используют более сложные сумматоры, рассматривать их в нашем обзоре будет излишним. Помимо сумматоров, процессоры также содержат узлы для деления и умножения, включая версии всех этих операций с плавающей запятой.
Объединение групп логических элементов для выполнения какой-либо функции, подобное этому, называется комбинационной логикой. Но этот тип логики не единственный, что встречается в компьютерах. Было бы мало толку, если бы мы не могли хранить данные или отслеживать состояние чего-либо. Для этого нам нужна секвенциальная логика, которая обеспечивает возможность хранить данные.
Секвенциальная логика строится путем подключения инверторов и других гейтов таким образом, что их выходы возвращают сигналы на вход гейтов. Эти контуры обратной связи используются для хранения одного бита данных и известны как статическое ОЗУ или SRAM (Static RAM). Статическим оно называется в противоположность динамическому (DRAM), поскольку сохраняемые в нём данные всегда напрямую связаны с положительным напряжением или землей.
Ниже показан стандартный способ имплементации одного бита SRAM на шести транзисторах. Верхний сигнал WL (Word Line, словная линия) является адресным, и когда он включен, данные, хранящиеся в этой 1-битной ячейке, подаются на битовую линию BL (Bit Line). Вывод BLB (Bit Line Bar, шина битовой линии) это просто инвертированное значение битовой линии, но физически это одна и та же линия. Помимо двух типов транзисторов, мы видим и знакомые нам схемы инверторов, выполненные на транзисторах M3/M1 и M2/M4.
SRAM используется для создания сверхбыстрых кэшей и регистров внутри процессоров. Такая память очень стабильна, но требует от шести до восьми транзисторов для хранения каждого бита данных. Это делает его чрезвычайно дорогим по стоимости, сложности и площади чипа по сравнению с Dynamic RAM. DRAM, в свою очередь, хранит данные в крошечном конденсаторе, а не с помощью логических вентилей. Динамическим оно называется потому, что напряжение на конденсаторе может динамически изменяться, поскольку оно не подключено напрямую к питанию или земле.
Поскольку для доступа к данным, хранящимся в конденсаторе, требуется только один транзистор на бит и конструкция схемы очень масштабируема, DRAM может быть «упакован» компактно и дешево. Одним из недостатков DRAM является то, что заряд в конденсаторе настолько мал, что его необходимо постоянно поддерживать. Именно поэтому при выключении компьютера все конденсаторы разряжаются и данные в оперативной памяти теряются.
Принципиальная схема DRAM. Address Line – адресная шина (словная линия); Bit Line – битовая шина (битовая линия); Transistor – транзистор; Storage capacitor – конденсатор; Ground – земля.
Такие производители, как Intel, AMD и Nvidia, не публикуют схем работы своих процессоров, поэтому и мы не можем предоставить точные схемы узлов современных процессоров. Однако этот простой сумматор позволяет получить достаточное представление о том, как даже самые сложные части процессора можно разбить на составляющие логические элементы, элементы памяти, и в конечном итоге – на транзисторы.
Теперь, когда мы знаем об устройстве некоторых компонентов процессора, нам нужно выяснить, как они соединяются и согласуются между собой. Все важнейшие узлы процессора подключены к тактовому сигналу (синхросигналу), который представляет собой чередование верхнего и нижнего уровня сигнала с заданным интервалом, называемым частотой. Логика внутри процессора обычно переключает значения и выполняет вычисления в момент переключения синхросигнала с низкого уровня на высокий. Синхронизируя все вместе, мы можем быть уверены, что данные всегда распределяются корректно по времени, тем самым исключая сбои в работе процессора.
Многие, наверное, слышали о так называемом «разгоне» – увеличении тактовой частоты процессора с целью повысить его производительность. Этот выигрыш в производительности достигается за счет более быстрого переключения транзисторов и внутрипроцессорной логики, чем предусмотрено производителем. Поскольку число тактов в секунду становится больше, то и операций может быть произведено больше, отчего и повышается производительность процессора. Но это справедливо лишь до определенного предела. Большинство современных процессоров работают с частотой от 3,0 до 4,5 ГГц, и за последнее десятилетие ситуация не сильно изменилась. Точно так же, как металлическая цепь не прочнее её самого слабого звена, процессор не может быть быстрее его самой медленной части. К концу каждого такта каждый из элементов процессора должен завершить свою работу. Если какой-то элемент не успевает, значит заданная частота слишком высока, и процессор не сможет работать. Разработчики называют эту самую медленную часть «критическим путем», и именно по ней производителем задаётся максимальная частота процессора. Выше определенной частоты транзисторы просто не могут переключаться достаточно быстро и начинают глючить или давать неправильные выходные сигналы.
Мы можем ускорить переключение транзисторов, повысив напряжение питания процессора, но это тоже срабатывает до определённого предела. Если подать слишком большое напряжение, то мы рискуем сжечь процессор. При увеличении частоты или повышении напряжения процессора, усиливаются его нагрев и потребляемая мощность. Это происходит потому, что мощность процессора прямо пропорциональна частоте и пропорциональна квадрату напряжения. Чтобы определить энергопотребление процессора, мы рассматриваем каждый транзистор как маленький конденсатор, который нужно заряжать или разряжать при изменении его значения.
Подача питания — настолько важная часть процессора, что в некоторых случаях до половины физических контактов на чипе может использоваться только для питания или заземления. Некоторые чипы при полной нагрузке могут потреблять больше 150 ампер, и весь этот ток должен крайне аккуратно управляться. Чтобы представить такое количество энергии, заметим: центральный процессор производит больше тепла на единицу площади, чем ядерный реактор.
Тактовый сигнал в современных процессорах отнимает примерно 30-40% от его общей мощности, потому что он очень сложен и должен управлять множеством различных устройств. Для сохранения энергии большинство процессоров с низким потреблением отключают части чипа во время их бездействия. Это реализуется отключением тактового сигнала (Clock Gating) или отключением питания (Power Gating).
Тактовые сигналы имеют ещё одну сложность при разработке процессора: так как их частоты постоянно растут, на их пути начинают вставать законы физики. Хоть скорость света и чрезвычайно высока, она недостаточно высока для высокопроизводительных процессоров. Если подключить тактовый сигнал к одному из концов чипа, то ко времени, когда сигнал достигнет другого конца, он уже будет значительно рассинхронизован. Чтобы синхронизировать все части чипа, тактовый сигнал распределяется при помощи так называемого H-дерева (H-Tree). Это структура, обеспечивающая равноудаленность всех конечных точек от центра.
Может показаться, что проектирование каждого отдельного транзистора, тактового сигнала и контакта питания в чипе – чрезвычайно монотонная и сложная задача, и это в самом деле так. Даже несмотря на то, что в таких компаниях, как Intel, Qualcomm и AMD работают тысячи инженеров, они не смогли бы вручную спроектировать каждый аспект чипа. Для их проектирования они используют различные специальные инструменты, помогающие создавать необходимые конструкции и схемы к ним. Такие инструменты обычно получают высокоуровневое описание того, что должен делать компонент, и определяют наилучшую аппаратную конфигурацию, удовлетворяющую этим требованиям. Зародилось технологическое направление под названием "Синтез высокого уровня" (High Level Synthesis), которое позволяет разработчикам задавать в коде желаемую функциональность, после чего компьютеры определяют, как оптимально достичь её в оборудовании.
Точно так же, как вы можете описывать компьютерные программы с помощью кода, проектировщики могут описывать кодом аппаратные устройства. Такие языки, как Verilog и VHDL позволяют разработчикам оборудования выражать функциональность любой создаваемой ими электрической схемы. После успешного выполнения симуляций и верификации таких проектов их можно материализовать в конкретные транзисторы, из которых будет состоять электрическая схема. Хоть этап верификации и не кажется столь же увлекательным, как проектирование нового кэша или ядра, он значительно важнее их. На каждого нанимаемого компанией инженера-проектировщика может приходиться пять или более инженеров по верификации.
Непросто осмыслить то, что в одном чипе может быть несколько миллиардов транзисторов и понять, что все они делают. Если разбить чип на его отдельные внутренние компоненты, становится немного легче. Из транзисторов составляются логические вентили, логические вентили соединяются в функциональные модули, выполняющие определённую задачу, а эти функциональные модули собираются вместе, образуя архитектуру компьютера, о которой мы говорили в первой части серии.
Бо́льшая часть работ по проектированию автоматизирована, но изложенное выше позволяет нам осознать, насколько сложен только что купленный нами новый процессор.
Эта вторая часть нашей серии посвящена процессу проектирования процессора. Мы рассмотрели транзисторы, логические элементы (они же вентили, гейты), подачу питания и синхронизирующих сигналов, синтез конструкции и верификацию. В третьей части мы узнаем, что требуется для физического производства чипа. Все компании любят хвастаться тем, насколько современен их техпроцесс (Intel 10 нм, Apple и AMD 7 нм, и т.д.), но что же на самом деле означают эти числа? Об этом мы расскажем в следующей части.
Несмотря на постоянные улучшения и стабильный прогресс с каждым новым поколением, каких-то фундаментальных сдвигов в индустрии процессоров не происходит уже давно. Переход от ламп к транзисторам был огромным шагом вперёд, также как переход от отдельных компонентов на интегральные схемы. Однако после этого ничего столь же революционного и масштабного не происходило.
Да, транзисторы стали меньше, чипы стали быстрее, а их производительность выросла в сотни раз, но мы начинаем наблюдать застой.
Это четвертая и последняя статья в нашей серии, посвященной разработке и изготовлению процессоров. Начав с высокоуровневого кода, мы узнали, как он компилируется в язык ассемблера и далее – в бинарные инструкции, с которыми работает процессор. Мы заглянули в архитектуру процессоров и поняли, как они обрабатывают инструкции. Затем мы внимательно рассмотрели различные отдельные составляющие процессора.
Мы увидели, как создаются все эти структуры, как обеспечивается согласованная работа миллиардов транзисторов и как из необработанного кремния физически производятся процессоры. Мы узнали об основных свойствах полупроводников и о том, как на самом деле выглядят внутренности чипа.
Перейдём к четвёртой части. Поскольку компании-производители не разглашают результаты исследований и подробности своих актуальных технологий, трудно с уверенностью сказать, что именно находится внутри вашего процессора. Однако мы можем проанализировать современные открытые исследования и понять, в каком направлении движется отрасль.
Одним из самых известных способов представления индустрии производства процессоров – это закон Мура, который гласит, что количество транзисторов в чипе удваивается примерно каждые полтора года. Долгое время этот закон оправдывал себя, но в последнее время рост стал замедляться. Транзисторы становятся настолько маленькими, что мы приближаемся к физическому пределу уменьшения размеров. Если не появится какой-либо прорывной технологии, нам придётся в будущем искать какие-то другие способы повышения производительности.
Закон Мура на протяжении последних 120 лет.
Этот график становится ещё интереснее, если обратить внимание на последние 7 точек – они относятся к GPU компании Nvidia, а не к процессорам общего назначения. Сверху: технологические периоды (механические устройства, реле, лампы, транзисторы, интегральные схемы); слева: стоимость вычислений в секунду (в "постоянных долларах"); снизу: годы. Иллюстрация Стива Джарветсона (Steve Jurvetson).
В то же время, очень многообещающе выглядит область квантовых вычислений. Я в этом не специалист, да почти и нет пока настоящих специалистов в этой области, поскольку технология лишь в процессе создания. Чтобы развеять мифы, скажу, что квантовые компьютеры не дадут вам 1000 кадров в секунду при рендеринге в реальном времени, например. Главное преимущество квантовых компьютеров на данный момент состоит в том, что они используют другие, более продвинутые и ранее недостижимые алгоритмы.
Один из прототипов квантового компьютера IBM.
В обычном компьютере транзистор либо включен, либо выключен, что соответствует 1 и 0. В квантовом компьютере возможна суперпозиция, когда бит может быть одновременно 0 и 1. Благодаря этой появившейся возможности ученые-кибернетики разрабатывают новые методы вычислений и могут решать задачи, неразрешимые с помощью существующих вычислительных мощностей. И дело не в том, что квантовые компьютеры быстрее, а в том, что они представляют собой принципиально новую модель вычислений, способную решать множество новых задач.
До массового внедрения этой технологии ещё 10-20 лет, так какие же тенденции наблюдаются сегодня в индустрии процессоров? Активно ведутся десятки исследований в разных областях, но я коснусь лишь нескольких, самых, на мой взгляд, значительных.
Растёт тенденция влияния гетерогенных вычислений. Это метод включения нескольких различных вычислительных элементов в одну систему. Большинству из нас знаком этот метод на примере отдельного GPU в компьютере. Центральный процессор очень гибок в настройке и может выполнять широкий спектр вычислений с адекватной скоростью. С другой стороны, GPU разработан специально для выполнения графических вычислений, таких как матричное перемножение. С подобными типами инструкции они справляются на порядки быстрее центрального процессора. Переложив некоторую часть нагрузки графическими вычислениями с CPU на GPU, мы можем ускорить выполнение расчетов. Любой программист легко оптимизирует своё ПО, нужным образом изменив алгоритм, а вот оптимизировать оборудование гораздо сложнее.
Но GPU – не единственная область, где применение акселерации становится обычным явлением. Большинство смартфонов имеют десятки аппаратных акселераторов, предназначенных для ускорения выполнения весьма специфических задач. Такой подход к вычислениям известен как «Море ускорителей» (Sea of Accelerators), и к примерам его применения можно привести криптографические процессоры, процессоры изображений, ускорители машинного обучения, кодеры/декодеры видео, биометрические процессоры и многое другое.
По мере того, как нагрузки становятся все более специализированными, разработчики оборудования включают в свои чипы все больше акселераторов. Провайдеры облачных сервисов, такие как AWS, начали предоставлять разработчикам карты FPGA для ускорения их вычислений в облаке. В отличие от обычных вычислительных элементов, таких как ЦП и GPU, имеющих жёсткую внутреннюю архитектуру, архитектура FPGA гибкая. Это практически программируемое оборудование, которое можно настроить в соответствии с нуждами пользователя.
Если требуется выполнять распознавание изображений, можно реализовать эти алгоритмы аппаратно. А чтобы сперва протестировать новое оборудование с помощью симуляции, прежде чем его фактически изготовлять, можно использовать FPGA. FPGA обеспечивает бо́льшую производительность и энергоэффективность, чем графические процессоры, но все же меньше, чем ASIC (application-specific integrated circuit, «интегральная схема специального назначения»). Другие компании, такие как Google и Nvidia, разрабатывают ASIC машинного обучения для ускорения распознавания и анализа изображений.
Взглянув на снимки кристаллов относительно современных процессоров, мы видим, что бо́льшую часть площади ЦП на самом деле занимает не само ядро. Всё бо́льшую долю занимают разного рода ускорители. Это позволило ускорить выполнение очень специализированных вычислений, а также значительно снизить энергопотребление.
Раньше при необходимости добавления в систему обработки видео, разработчики просто добавляли в систему новый чип. Однако это крайне неэффективный подход. Каждый раз, когда сигналу нужно пройти по физическому проводнику от одного чипа к другому, требуется огромное количество энергии на бит. Сама по себе крошечная доля джоуля не кажется особо значительной, но при передаче данных внутри, а не снаружи чипа, она используется на 3-4 порядка эффективнее. Благодаря интеграции таких акселераторов с ЦП, мы наблюдали рост количества чипов со сверхнизким энергопотреблением.
И всё же ускорители не идеальны. Чем больше мы добавляем их в схемы, тем менее гибким становится чип, и мы начинаем жертвовать общей производительностью ради пиковой производительности специализированных видов вычислений. На каком-то этапе весь чип просто превращается в набор акселераторов и перестаёт быть ЦП как таковым. Баланс между производительностью специализированных вычислений и общей производительностью всегда очень тщательно настраивается. Это разногласие между оборудованием общего назначения и специализированными нагрузками называется разрывом специализации (specialization gap).
Если некоторым кажется, что возможности GPU/Machine Learning уже достигли своего апогея, мы можем ожидать, что всё больший объём вычислений будет передаваться специализированным ускорителям. Облачные вычисления и ИИ продолжают развиваться, поэтому GPU выглядят лучшим решением для достижения требуемого уровня объёма вычислений.
Другой областью, где разработчики ищут способы повышения производительности, является память. Традиционно, чтение и запись значений всегда были одним из самых серьёзных «узких мест» для процессоров. Нам могут помочь быстрые и большие кэши, но считывание из ОЗУ или с SSD может занимать десятки тысяч тактовых циклов. Поэтому инженеры часто рассматривают доступ к памяти как более затратный, чем сами вычисления. Если процессор хочет сложить два числа, то ему сначала нужно вычислить адреса памяти, по которым хранятся числа, выяснить, на каком уровне иерархии памяти есть эти данные, считать данные в регистры, выполнить вычисления, вычислить адрес приёмника и записать значение в нужное место. Для простых инструкций, выполнение которых может занимать один-два цикла, это чрезвычайно неэффективно.
Новаторская идея, которую сейчас активно исследуют — это метод под названием Near-Memory Computing (NMC, “околопамятные вычисления”). Вместо того, чтобы извлекать небольшие фрагменты данных из памяти и вычислять их быстрым процессором, исследователи делают наоборот. Они экспериментируют с созданием небольших процессоров непосредственно в контроллерах памяти ОЗУ или SSD. Разместив вычисления ближе к памяти, мы можем получить огромную экономию энергии и времени, ведь теперь нет нужды гонять данные столь много и долго. Вычислительные модули имеют прямой доступ к нужным им данным, поскольку находятся непосредственно в памяти. Эта идея всё ещё находится в зачаточном состоянии, но результаты выглядят многообещающе.
Одно из препятствий, стоящих на пути реализации near-memory computing — это ограничения, накладываемые процессом изготовления чипа. Как говорилось в третьей части, процесс кремниевого производства очень сложен и состоит из десятков этапов. Эти процессы обычно специализированы для изготовления либо быстрых логических элементов, либо элементов памяти. Если попытаться создать чип памяти с помощью процесса, оптимизированного для вычислительных элементов, то получится чип с чрезвычайно низкой плотностью элементов. Если же попробовать создать процессор с помощью процесса, предназначенного для модулей памяти, то получим очень низкую производительность и большие тайминги.
Пример 3D-интеграции, демонстрирующий вертикальные соединения между слоями транзисторов.
Одним из возможных решений этой проблемы является трёхмерная интеграция (3D Integration). Традиционные процессоры обладают одним очень широким слоем транзисторов, и это имеет свои ограничения. Как видно из названия, 3D-интеграция — это процесс расположения нескольких слоёв транзисторов друг над другом для повышения плотности и снижения задержек. Вертикальные проводники, производимые на разных процессах изготовления, используются для соединений между слоями. Эта идея была предложена уже давно, но индустрия отказалась от неё из-за серьёзных сложностей в её реализации. В последнее время мы наблюдаем возникновение технологии накопителей 3D NAND и возрождение этой области исследований.
Наряду с физическими и архитектурными изменениями, на всю индустрию полупроводников сильно повлияет тенденция усиления внимания к безопасности. До недавнего времени о безопасности процессоров думали чуть ли не в последнюю очередь. Это как если бы Интернет, электронная почта и многие другие системы, которые мы сегодня активно используем, разрабатывались почти без учёта безопасности. Все существующие меры защиты «прикручивались» по мере случавшихся инцидентов, чтобы мы чувствовали себя защищёнными. Касательно процессоров, подобная практика больно ударила по производителям, и особенно по Intel.
Уязвимости Spectre и Meltdown — это, вероятно, самые известные примеры того, как проектировщики добавляют функции, значительно ускоряющие процессор, не в полной мере осознавая связанные с этим угрозы. При разработке же современных процессоров гораздо большее внимание уделяется безопасности как ключевой части архитектуры. При её повышении часто страдает производительность, но учитывая ущерб, который компании могут понести из-за появления серьёзных уязвимостей, очевидно, что безопасностью пренебрегать не стоит в той же мере, как производительностью.
В предыдущих частях нашей серии мы коснулись таких техник, как высокоуровневый синтез, позволяющий проектировщикам сначала описать структуру на языке высокого уровня, а затем позволить сложным алгоритмам определить оптимальную для выполнения функции аппаратную конфигурацию. С каждым поколением этапы проектирования становятся всё более дорогостоящими, поэтому инженеры ищут способы ускорения разработки. Следует ожидать, что в дальнейшем и эта тенденция проектирования оборудования при помощи ПО будет только усиливаться.
Будущее предсказать невозможно, но рассмотренные нами в статье инновационные идеи и области исследований могут служить своего рода дорожной картой наших ожиданий в сфере проектирования процессоров будущего. Что с уверенностью можно сказать, так это то, что мы близимся к концу типичных усовершенствований процесса производства. Чтобы и дальше продолжать увеличивать производительность в каждом поколении, разработчикам придётся искать ещё более сложные решения.
Надеемся, что наша серия из четырёх статей пробудила ваш интерес к тому, как проектируются и производятся процессоры, как контролируется их качество и многому другому. Существует бесконечное количество материалов по этой теме, и если бы мы попытались раскрыть их все, то каждая из статей заняла бы целый университетский курс. Хочется надеяться, вы узнали для себя что-то новое и теперь лучше понимаете, насколько сложны компьютеры на каждом из уровней. Если у вас есть предложения, какую тему нам стоит рассмотреть поглубже, мы всегда готовы выслушать их.
Несмотря на постоянные улучшения и стабильный прогресс с каждым новым поколением, каких-то фундаментальных сдвигов в индустрии процессоров не происходит уже давно. Переход от ламп к транзисторам был огромным шагом вперёд, также как переход от отдельных компонентов на интегральные схемы. Однако после этого ничего столь же революционного и масштабного не происходило.
Да, транзисторы стали меньше, чипы стали быстрее, а их производительность выросла в сотни раз, но мы начинаем наблюдать застой.
Это четвертая и последняя статья в нашей серии, посвященной разработке и изготовлению процессоров. Начав с высокоуровневого кода , мы узнали, как он компилируется в язык ассемблера и далее – в бинарные инструкции, с которыми работает процессор. Мы заглянули в архитектуру процессоров и поняли, как они обрабатывают инструкции. Затем мы внимательно рассмотрели различные отдельные составляющие процессора .
Мы увидели, как создаются все эти структуры, как обеспечивается согласованная работа миллиардов транзисторов и как из необработанного кремния физически производятся процессоры. Мы узнали об основных свойствах полупроводников и о том, как на самом деле выглядят внутренности чипа.
Перейдём к четвёртой части. Поскольку компании-производители не разглашают результаты исследований и подробности своих актуальных технологий, трудно с уверенностью сказать, что именно находится внутри вашего процессора. Однако мы можем проанализировать современные открытые исследования и понять, в каком направлении движется отрасль.
Одним из самых известных способов представления индустрии производства процессоров – это закон Мура, который гласит, что количество транзисторов в чипе удваивается примерно каждые полтора года. Долгое время этот закон оправдывал себя, но в последнее время рост стал замедляться. Транзисторы становятся настолько маленькими, что мы приближаемся к физическому пределу уменьшения размеров. Если не появится какой-либо прорывной технологии, нам придётся в будущем искать какие-то другие способы повышения производительности.
Закон Мура на протяжении последних 120 лет.
Этот график становится ещё интереснее, если обратить внимание на последние 7 точек – они относятся к GPU компании Nvidia, а не к процессорам общего назначения. Сверху: технологические периоды (механические устройства, реле, лампы, транзисторы, интегральные схемы); слева: стоимость вычислений в секунду (в "постоянных долларах"); снизу: годы. Иллюстрация Стива Джарветсона (Steve Jurvetson).
В то же время, очень многообещающе выглядит область квантовых вычислений. Я в этом не специалист, да почти и нет пока настоящих специалистов в этой области, поскольку технология лишь в процессе создания. Чтобы развеять мифы, скажу, что квантовые компьютеры не дадут вам 1000 кадров в секунду при рендеринге в реальном времени, например. Главное преимущество квантовых компьютеров на данный момент состоит в том, что они используют другие, более продвинутые и ранее недостижимые алгоритмы.
Один из прототипов квантового компьютера IBM.
В обычном компьютере транзистор либо включен, либо выключен, что соответствует 1 и 0. В квантовом компьютере возможна суперпозиция, когда бит может быть одновременно 0 и 1. Благодаря этой появившейся возможности ученые-кибернетики разрабатывают новые методы вычислений и могут решать задачи, неразрешимые с помощью существующих вычислительных мощностей. И дело не в том, что квантовые компьютеры быстрее, а в том, что они представляют собой принципиально новую модель вычислений, способную решать множество новых задач.
До массового внедрения этой технологии ещё 10-20 лет, так какие же тенденции наблюдаются сегодня в индустрии процессоров? Активно ведутся десятки исследований в разных областях, но я коснусь лишь нескольких, самых, на мой взгляд, значительных.
Растёт тенденция влияния гетерогенных вычислений. Это метод включения нескольких различных вычислительных элементов в одну систему. Большинству из нас знаком этот метод на примере отдельного GPU в компьютере. Центральный процессор очень гибок в настройке и может выполнять широкий спектр вычислений с адекватной скоростью. С другой стороны, GPU разработан специально для выполнения графических вычислений, таких как матричное перемножение. С подобными типами инструкции они справляются на порядки быстрее центрального процессора. Переложив некоторую часть нагрузки графическими вычислениями с CPU на GPU, мы можем ускорить выполнение расчетов. Любой программист легко оптимизирует своё ПО, нужным образом изменив алгоритм, а вот оптимизировать оборудование гораздо сложнее.
Но GPU – не единственная область, где применение акселерации становится обычным явлением. Большинство смартфонов имеют десятки аппаратных акселераторов, предназначенных для ускорения выполнения весьма специфических задач. Такой подход к вычислениям известен как «Море ускорителей» (Sea of Accelerators), и к примерам его применения можно привести криптографические процессоры, процессоры изображений, ускорители машинного обучения, кодеры/декодеры видео, биометрические процессоры и многое другое.
По мере того, как нагрузки становятся все более специализированными, разработчики оборудования включают в свои чипы все больше акселераторов. Провайдеры облачных сервисов, такие как AWS, начали предоставлять разработчикам карты FPGA для ускорения их вычислений в облаке. В отличие от обычных вычислительных элементов, таких как ЦП и GPU, имеющих жёсткую внутреннюю архитектуру, архитектура FPGA гибкая. Это практически программируемое оборудование, которое можно настроить в соответствии с нуждами пользователя.
Если требуется выполнять распознавание изображений, можно реализовать эти алгоритмы аппаратно. А чтобы сперва протестировать новое оборудование с помощью симуляции, прежде чем его фактически изготовлять, можно использовать FPGA. FPGA обеспечивает бо́льшую производительность и энергоэффективность, чем графические процессоры, но все же меньше, чем ASIC (application-specific integrated circuit, «интегральная схема специального назначения»). Другие компании, такие как Google и Nvidia, разрабатывают ASIC машинного обучения для ускорения распознавания и анализа изображений.
Взглянув на снимки кристаллов относительно современных процессоров, мы видим, что бо́льшую часть площади ЦП на самом деле занимает не само ядро. Всё бо́льшую долю занимают разного рода ускорители. Это позволило ускорить выполнение очень специализированных вычислений, а также значительно снизить энергопотребление.
Раньше при необходимости добавления в систему обработки видео, разработчики просто добавляли в систему новый чип. Однако это крайне неэффективный подход. Каждый раз, когда сигналу нужно пройти по физическому проводнику от одного чипа к другому, требуется огромное количество энергии на бит. Сама по себе крошечная доля джоуля не кажется особо значительной, но при передаче данных внутри, а не снаружи чипа, она используется на 3-4 порядка эффективнее. Благодаря интеграции таких акселераторов с ЦП, мы наблюдали рост количества чипов со сверхнизким энергопотреблением.
И всё же ускорители не идеальны. Чем больше мы добавляем их в схемы, тем менее гибким становится чип, и мы начинаем жертвовать общей производительностью ради пиковой производительности специализированных видов вычислений. На каком-то этапе весь чип просто превращается в набор акселераторов и перестаёт быть ЦП как таковым. Баланс между производительностью специализированных вычислений и общей производительностью всегда очень тщательно настраивается. Это разногласие между оборудованием общего назначения и специализированными нагрузками называется разрывом специализации (specialization gap).
Если некоторым кажется, что возможности GPU/Machine Learning уже достигли своего апогея, мы можем ожидать, что всё больший объём вычислений будет передаваться специализированным ускорителям. Облачные вычисления и ИИ продолжают развиваться, поэтому GPU выглядят лучшим решением для достижения требуемого уровня объёма вычислений.
Другой областью, где разработчики ищут способы повышения производительности, является память. Традиционно, чтение и запись значений всегда были одним из самых серьёзных «узких мест» для процессоров. Нам могут помочь быстрые и большие кэши, но считывание из ОЗУ или с SSD может занимать десятки тысяч тактовых циклов. Поэтому инженеры часто рассматривают доступ к памяти как более затратный, чем сами вычисления. Если процессор хочет сложить два числа, то ему сначала нужно вычислить адреса памяти, по которым хранятся числа, выяснить, на каком уровне иерархии памяти есть эти данные, считать данные в регистры, выполнить вычисления, вычислить адрес приёмника и записать значение в нужное место. Для простых инструкций, выполнение которых может занимать один-два цикла, это чрезвычайно неэффективно.
Новаторская идея, которую сейчас активно исследуют — это метод под названием Near-Memory Computing (NMC, “околопамятные вычисления”). Вместо того, чтобы извлекать небольшие фрагменты данных из памяти и вычислять их быстрым процессором, исследователи делают наоборот. Они экспериментируют с созданием небольших процессоров непосредственно в контроллерах памяти ОЗУ или SSD. Разместив вычисления ближе к памяти, мы можем получить огромную экономию энергии и времени, ведь теперь нет нужды гонять данные столь много и долго. Вычислительные модули имеют прямой доступ к нужным им данным, поскольку находятся непосредственно в памяти. Эта идея всё ещё находится в зачаточном состоянии, но результаты выглядят многообещающе.
Одно из препятствий, стоящих на пути реализации near-memory computing — это ограничения, накладываемые процессом изготовления чипа. Как говорилось в третьей части, процесс кремниевого производства очень сложен и состоит из десятков этапов. Эти процессы обычно специализированы для изготовления либо быстрых логических элементов, либо элементов памяти. Если попытаться создать чип памяти с помощью процесса, оптимизированного для вычислительных элементов, то получится чип с чрезвычайно низкой плотностью элементов. Если же попробовать создать процессор с помощью процесса, предназначенного для модулей памяти, то получим очень низкую производительность и большие тайминги.
Пример 3D-интеграции, демонстрирующий вертикальные соединения между слоями транзисторов.
Одним из возможных решений этой проблемы является трёхмерная интеграция (3D Integration). Традиционные процессоры обладают одним очень широким слоем транзисторов, и это имеет свои ограничения. Как видно из названия, 3D-интеграция — это процесс расположения нескольких слоёв транзисторов друг над другом для повышения плотности и снижения задержек. Вертикальные проводники, производимые на разных процессах изготовления, используются для соединений между слоями. Эта идея была предложена уже давно, но индустрия отказалась от неё из-за серьёзных сложностей в её реализации. В последнее время мы наблюдаем возникновение технологии накопителей 3D NAND и возрождение этой области исследований.
Наряду с физическими и архитектурными изменениями, на всю индустрию полупроводников сильно повлияет тенденция усиления внимания к безопасности. До недавнего времени о безопасности процессоров думали чуть ли не в последнюю очередь. Это как если бы Интернет, электронная почта и многие другие системы, которые мы сегодня активно используем, разрабатывались почти без учёта безопасности. Все существующие меры защиты «прикручивались» по мере случавшихся инцидентов, чтобы мы чувствовали себя защищёнными. Касательно процессоров, подобная практика больно ударила по производителям, и особенно по Intel.
Уязвимости Spectre и Meltdown — это, вероятно, самые известные примеры того, как проектировщики добавляют функции, значительно ускоряющие процессор, не в полной мере осознавая связанные с этим угрозы. При разработке же современных процессоров гораздо большее внимание уделяется безопасности как ключевой части архитектуры. При её повышении часто страдает производительность, но учитывая ущерб, который компании могут понести из-за появления серьёзных уязвимостей, очевидно, что безопасностью пренебрегать не стоит в той же мере, как производительностью.
В предыдущих частях нашей серии мы коснулись таких техник, как высокоуровневый синтез, позволяющий проектировщикам сначала описать структуру на языке высокого уровня, а затем позволить сложным алгоритмам определить оптимальную для выполнения функции аппаратную конфигурацию. С каждым поколением этапы проектирования становятся всё более дорогостоящими, поэтому инженеры ищут способы ускорения разработки. Следует ожидать, что в дальнейшем и эта тенденция проектирования оборудования при помощи ПО будет только усиливаться.
Будущее предсказать невозможно, но рассмотренные нами в статье инновационные идеи и области исследований могут служить своего рода дорожной картой наших ожиданий в сфере проектирования процессоров будущего. Что с уверенностью можно сказать, так это то, что мы близимся к концу типичных усовершенствований процесса производства. Чтобы и дальше продолжать увеличивать производительность в каждом поколении, разработчикам придётся искать ещё более сложные решения.
Надеемся, что наша серия из четырёх статей пробудила ваш интерес к тому, как проектируются и производятся процессоры, как контролируется их качество и многому другому. Существует бесконечное количество материалов по этой теме, и если бы мы попытались раскрыть их все, то каждая из статей заняла бы целый университетский курс. Хочется надеяться, вы узнали для себя что-то новое и теперь лучше понимаете, насколько сложны компьютеры на каждом из уровней. Если у вас есть предложения, какую тему нам стоит рассмотреть поглубже, мы всегда готовы выслушать их.
Читайте также: