Меню

Архитектура цп: коротко о том как устроен CPU

Содержание

коротко о том как устроен CPU

Доброго времени суток. В этой статье вы получите развернутый ответ на вопрос «что такое архитектура процессора». Также после ее прочтения вы узнаете о разновидностях архитектуры и научитесь различать их обозначения.

Транзисторы в кристалде процессора

 

Объяснение термина

Под архитектурой процессора понимается комбинация из:

  • Микроархитектуры — способ ее реализации, то есть составные части проца и методы их взаимодействия между собой и описанными ниже компонентами;
  • АНК — набор команд, включая модель исполнения, регистры устройства, форматы данных и адресов.
  • Микрокода — делает понятными команды уровня АНК для микроархитектуры.

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

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

Ядро cpu

 

Классификация архитектур

По скорости и количеству выполняемых команд архитектуры делятся на:

  • CISC. На английском языке расшифровывается как «Complex Instruction Set Computing», то есть «Комплексный набор команд». Устройствам этого типа свойственно большое количество режимов адресации и команд разного формата и длины, а также сложная кодировка инструкции.
  • RISC. Первое слово в расшифровке заменено на «Reduced», что на нашем языке — «Сокращенный». Это значит, что все команды имеют одинаковый формат и кодировку.
  • MISC (Multipurpose — Многоцелевой ). База элементов делится на две части, которые находятся или в одном корпусе, или в отдельных. Главной выступает RISC CPU. Он дополнен другой частью — постоянным запоминающим устройством микропрограммного управления. Системе присущи характеристики CISC. Большинство команд выполняет первая часть, а команды расширения преобразуются в адрес микропрограммы.

Стопка cpu

Также существует классификация процессоров, и соответственно архитектур, по назначению:

  • Графические. Как видеокарта отвечает за визуализацию объектов на экране.
  • Математические. Нацелены на расширение набора команд, выполняемых центральным процессором, для решения различных математических задач.
  • Цифровые сигнальные. Специализированные устройства, предназначенные для обработки оцифрованных сигналов.

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

 

 

Разбор обозначений

В теме о процессорах вы можете столкнуться с их цифровыми обозначениями типа x64, x86 и пр. Давайте разберемся, что все это значит. Разложу по полочкам.

8086 и компания

В 1978 году компания Intel выпустила 16-битный процессор, получивший название 8086.

8086

Intel i386

 

После него выходили другие модели, в наименованиях которых первые две цифры оставались прежними, а последние менялись на 88, 186, 286, 386, 486 и прочие.

Вот пример i386.

 

Как вы заметили, почти все имена заканчиваются одинаково, поэтому все семейство объединили под условное обозначение x86. Оно устоялось среди пользователей и применялось даже когда Интел начала давать своим продуктам словарные названия типа Пентиум, Кор, Атом и т. д. Переняли эту «моду» и другие производители устройств, совместимых с этим семейством, — IBM, VIA, AMD, Cyrix и др.

Чаще всего это обозначение сейчас используется по отношению к 32-битным процессорам. Они также могут называться, к примеру, i386, i486, i586, когда требуется дать более точные сведения о наборе инструкций.

 

Совершенствование до 64 бит

Компания Intel модернизировала процессоры с 16-битной шиной до 32 бит. Однако AMD приложила усилия к усовершенствованию их до х64. Первый такой продукт она выпустила в 2003 году, не став заморачиваться над названием — просто «AMD64».

Архитектура процессора - что это за хитрое понятие??

Чтобы показать повышенную разрядность процессоров, стали к обозначению «x86» добавлять «64», к примеру, x86_64.

Интел решила выделиться, помечая такие устройства сначала как «IA-32e», а потом «EM64T». Но сейчас чаще можно встретить «Intel 64».

 

Как узнать архитектуру?

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

 

Средства системы

Выполните следующие действия:

  • Откройте командную строку через меню «Пуск — Программы — Стандартные» или другим удобным способом.
  • Впишите в нее слово systeminfo.
  • Нажмите Enter.

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

Архитектура процессора

Другой способ:

  • Щелкните правой кнопкой мыши на значке «Мой компьютер»;
  • Откройте «Свойства»;
  • Перейдите в «Диспетчер устройств»;
  • Кликните пункт «Процессор».

И тоже получите все данные о нем.

Вызываем диспетчер устройств

Сторонние программы

X86-64 в CPU-ZОдной из хороших программ, помогающих узнать все о проце, является CPU-Z.

Она бесплатная и распространенная, поэтому вы без проблем ее отыщите и скачаете.

Вам нужно лишь установить и запустить ее, чтобы посмотреть необходимую информацию.

 

В качестве альтернативного варианта могу предложить еще одну достойную прогу — AIDA 64. Она платная (Есть триал период), зато может рассказать все о вашем железе в целом, не только о ЦП.

Получить сведения о процессоре через нее можно, перейдя по разделам «Компьютер — Системная плата — ЦП».

Тоже и в АИДА

На этом буду заканчивать.

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

До скорого.

Собственная платформа. Часть 0.1 Теория. Немного о процессорах / Хабр

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

4004

Принимаются любые замечания!



Исторически сложилось, что существуют много процессоров и много архитектур. Но многие архитектуры имеют схожести. Специально для этого появились «Группы» архитектур типа RISC, CISC, MISC, OISC (URISC). Кроме того они могут иметь разные архитектуры адресации памяти (фон Неймана, Гарвард). У каждого процессора есть своя архитектура. Например большинство современных архитектур это RISC (ARM, MIPS, OpenRISC, RISC-V, AVR, PIC** и т.д.), но есть архитектуры которые выиграли просто за счет других факторов (Например удобство/цена/популярность/etc) Среди которых x86, x86-64 (Стоит отметить, что x86-64 и x86 в последних процессорах используют микрокод и внутри них стоит RISC ядро), M68K. В чем же их отличие?


RISC

Reduced Instruction Set Computer — Архитектура с уменьшенным временем выполнения инструкций (из расшифровка RISC можно подумать, что это уменьшенное количество инструкций, но это не так). Данное направления развилось в итоге после того, как оказалось, что большинство компиляторов того времени не использовали все инструкции и разработчики процессоров решили получить больше производительности использую Конвейеры. В целом RISC является золотой серединой между всеми архитектурами.

Яркие примеры данной архитектуры: ARM, MIPS, OpenRISC, RISC-V


TTA

Что такое TTA? ТТА это Архитектура на основе всего одной инструкции перемещения из одного адреса памяти в другую. Данный вариант усложняет работу компилятора зато дает большую производительность. У данной архитектуры есть единственный недостаток: Сильная зависимость от шины данных. Именно это и стало причиной ее меньшей популярности. Надо отметить что TTA является разновидностью OISC.

Яркие примеры: MOVE Project


OISC (URISC)?

One Instruction Set Computer — Архитектура с единственной инструкцией. Например SUBLEQ. Такие архитектуры часто имеют вид: Сделать действие и в зависимости от результата сделать прыжок или продолжить исполнение. Зачастую ее реализация достаточно простая, производительность маленькая, при этом снова ограничение шиной данных.

Яркие примеры: BitBitJump, ByteByteJump, SUBLEQ тысячи их!


CISC

CISC — Complex Instruction Set Computer — ее особенность в увеличенных количествах действий за инструкцию. Таким образом можно было теоретически увеличить производительность программ за счет увеличения сложности компилятора. Но по факту у CISC плохо были реализованы некоторые инструкции т.к. они редко использовались, и повышение производительности не было достигнуто. Особенностью этой группы является еще ОГРОМНАЯ Разница между архитектурами. И несмотря на названия были архитектуры с маленьким количеством инструкций.

Яркие примеры: x86, M68K



Архитектура фон Неймана

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


Архитектура гарварда

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



Конвейеры

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

pipeline
На картинке более понятно, не правда?


IF — получение инструкции,
ID — расшифровка инструкции,
EX — выполнение,
MEM — доступ к памяти,
WB — запись в регистр.

Вроде все просто? А вот и нет! Проблема в том что например прыжок (jmp/branch/etc) заставляют конвейер начать исполнение (получение след. инструкции) заново таким образом вызывая задержку в 2-4 такта перед исполнение следующей инструкции.


Расширение существующих архитектур

Достаточно популярной техникой является добавление в уже существующую архитектуру больше инструкций через расширения. Ярким примером является SSE под x86. Этим же грешит ARM и MIPS и практически все. Почему? Потому что нельзя создать унивирсальную архитектуру.

Другим вариантом является использование других архитектур для уменьшения размера инструкций.
Яркий пример: ARM со своим Thumb, MIPS с MIPS16.


В видеокартах часто встречается много ядер и из-за этой особенности появилась потребность в дополнительных решениях. Если конвейеры можно встретить даже в микроконтроллерах то решения используемых в GPU встречаются редко. Например Masked Execution (Встречается в инструкциях ARM, но не в Thumb-I/II). Еще есть другие особенность: это уклон в сторону Floating Number (Числа с плавающей запятой), Уменьшение производительности в противовес большего количества ядер и т.д.


Masked Execution

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

Но Зачем?

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


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


Прерывания

Прерывания это техника при которой исполняемый в данный момент код приостанавливается для выполнения какой-то другой задачи при каких-то условиях. Например при доступе в несуществующий участок памяти вызывается HardFault или MemoryFault прерывания или исключения. Или например если таймер отсчитал до нуля. Это позволяет не бездействовать пока нужно ждать какое-то событие.

Какие недостатки? Вызов прерывания это несколько тактов простоя и несколько при возврате из прерывания. Так же несколько инструкций в начале кода будет занято инструкциями для Таблицы прерываний.


Exception (исключения)

Но кроме прерываний еще существуют исключений которые возникают например при деления на ноль. Зачастую его совмещают с прерываниями и системными вызовами, как например в MIPS. Исключения не всегда присутствуют в процессоре например как в AVR или младших PIC


Системные вызовы

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


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


Привилегированный режим

Это режим в котором стартует процессор. В таком режиме программа или ОС имеют полный доступ к памяти в обход MMU/MPU. Все программы запускаются в непривилегированном режиме во избежания прямого доступа к аппаратным подсистемам программ для этого не предназначенных. Например вредоносным программам. В Windows ее часто называют Ring-0, а в *nix — системным. Не стоит путать Привелигированный пользователь и Привилегированный режим ибо в руте вы все еще не можете иметь прямой доступ к аппаратуре (можно загрузить системный модуль который позволит это сделать, но об этом чуть позже 🙂


MPU и MMU

MMU

MPU и MMU используется в современных системах чтобы изолировать несколько приложений. НО если MMU позволяет «передвинуть» память то MPU позволяет только блокировать доступ к памяти/запуск кода в памяти.


PIC (PIE)

Что такое PIE? (PIC не использую для избежания путаницы с МК PIC). PIE это техника благодаря которой компилятор генерирует код который будет работать в любом месте в памяти. Эта техника в совмещении с MPU позволяет компилировать высокие языки программирования которые будут работать и с MPU.


Популярная техника SIMD используется для того, что бы за один такт выполнять несколько действий над несколькими регистрами. Иногда бывают в качестве дополнений к основной архитектуре, например, как в MIPS, ARM со своими NEON/VFP/etc, x86 со своим SSE2.


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


Что такое регистр статуса? Это регистр который хранит состояние процессора. Например находится ли процессор в привилегированном режиме, чем закончилась операция последнего сравнения.

Используется в связке с Masked Execution. Некоторые разработчики специально исключают регистр статуса ибо он может являться узким местом как поступили в MIPS.


В MIPS нет отдельной инструкции загрузки константы в память, но есть инструкция addi и ori которая позволяет в связке с нулевым регистром ($0) эмулировать работу загрузки константы в регистр. В других архитектурах она присутствует. Я затронул эту тему, потому что она пригодиться нам в статьях с практикой.


Идут множество споров насчет того сколько должно быть операндов в арифметических инструкциях. Например в MIPS используется вариант с 3-мя регистрами. 2 операнда, 1 регистр записи. С другой стороны, использование двух операндов позволяет сократить код за счет уменьшения размера инструкции. Пример совмещения является MIPS16 в MIPS и Thumb-I в ARM. В плане производительности они практически идентичны (Если исключать размер инструкции как фактор).


Порядок байт. Возможно вам знакомы Выражения Big-Endian и Little-Endian. Они описывают порядок байт в инструкциях/в регистрах/в памяти/etc. Здесь думаю все просто :). Есть процессоры которые совмещают режимы, как MIPS, или которые используют одну систему команд, но имеют разный порядок байт, например ARM.


Итак, что такое битность процессора? Многие считают, что это битность шины данных, но это не так. Почему? В ранние переоды микроконтроллеров и микропроцессоров шина могла быть, например, 4-х битной, но передавала пакетами по 8 бит. Для программы казалось, что это 8-и битный режим, но это была иллюзия, как и сейчас. Например, в ARM SoC-ах часто применяют 128-и битную шину данных или инструкций.


Что такое сопроцессоры? Сопроцессоры являются элементами процессора или внешней микросхемой. Они позволяют исполнять инструкции, которые слишком громоздки для основной части процессора. Как яркий пример, сопроцессоры в MIPS для деления и умножения. Или например 387 для 80386, который добавлял поддержку чисел с плавающей запятой. А в MIPS сопроцессоров было много и они выполняли свои роли: контролировали прерывания, исключения и системные вызовы. Часто сопроцессоры имеют собственные инструкции и на системах, где этих инструкций нет, (пример ARM) эмулируют ее через Trap-ы (ловушки?). Несмотря на костыльность и маленькую производительность, они часто являются единственным выбором в микроконтроллерах.


Атомартность операций обеспечивает потоко-независимое исполнение за счет инструкций, которые выполняют несколько действий за один псевдотакт.

Вариант другого решения атомарность переферии. Например для установки ножки в STM32 в высокое и низкое состояние используется разные регистры, что позволяет иметь атомарность на уровне переферии.


Вы, навярняка, слышали о L1, L2, L3 и регистрах. Если коротко, процессор анализирует часть кода, чтобы предугадать прыжки и доступ в память и зараннее просит кеш получить эти данные из памяти. Кеш зачастую бывает прозрачным для программы, но бывают и исключения из этого правила. Например, в программных ядрах в ПЛИС используется програмный кеш.

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


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


Stack

Стек? Я видел Стек в .NET и в Java! Что же, Вы частично правы. Стек существует, но он никогда не был апаратным в большинства процессорах. Например в MIPS его по просту нет. Спросите КАК ТАК ТО?! Ответ прост. Стек это просто доступ к памяти которую не нужно резервировать (очень грубое определение). Стек используется для вызова функций, передачи аргументов, сохранения регистров для того чтобы востановить их после выполнения функции и т.д.

Спросите тогда что такое куча (Heap)? Куча это память размером намного больше чем стек (Стек обычно ~1MB). В хипе храниться все глобальное. Например все указатели полученные с помощю Malloc указывают на часть куча. А указатели хранятся в стеке или в регистрах. С помощью инструкций загрузки данных относительно регистра можно ускорить работу стека и других доступов к памяти по типу стека, поскольку не нужно постоянно использовать операции PUSH/POP, INC/DEC или ADDI, SUBI (добавить константу), чтобы получить данные глубже по стеку, а можно просто использовать доступ относительно стека с отрицательным смещением.


Не буду описывать регистры слишком подробно. Это мы затронем в практической статье.

В x86 регистров достаточно мало. В MIPS используется увеличенное количество регистров, а именно 31 ($0 имеет значение всегда равное нулю). В процессоре университета Беркли использовались регистровые окна, которые жестки ограничивали вложенность функций, при этом имея лучшую производительность. В других же, таких как AVR, ограничили использование регистров. Для примера: три 16-битных можно трактовать как шесть восьмибитных, где первые 16ть недоступны при некоторых операциях. Я считаю, что лучший метод был выбран MIPS-ом. Это мое сугубо личное мнение.


Что такое выравнивание? Оставлю-ка я этот вопрос вам 🙂


Это конец первой главы нулевой части. Вся серия будет крутиться вокруг темы создания собственного процессора. Собственной операционной системы. Собственного ассемблера. Собственного компилятора и много чего другого.

Нулевые части будут посвящены теории. Я сомневаюсь что доведу всю серию до победного конца, но попытка не пытка! )

основы архитектуры компьютеров / Хабр


Мы воспринимаем центральный процессор как «мозг» компьютера, но что это значит на самом деле? Что именно происходит внутри миллиардов транзисторов, благодаря которым работает компьютер? В нашей новой мини-серии из четырёх статей мы рассмотрим процесс создания архитектуры компьютерного оборудования и расскажем о принципах его работы.

В этой серии мы расскажем о компьютерной архитектуре, проектировании процессорных плат, VLSI (very-large-scale integration), производстве чипов и тенденциях будущего в области вычислительной техники. Если вам было интересно разобраться в подробностях работы процессоров, то начинать изучение лучше с этой серии статей.

Мы начнём с очень высокоуровневого объяснения того, чем занимается процессор и как строительные блоки соединяются в функционирующую конструкцию. В том числе мы рассмотрим процессорные ядра, иерархию памяти, предсказание ветвлений и другое. Во-первых, нам нужно дать простое определение тому, что делает ЦП. Простейшее объяснение: процессор следует набору инструкций для выполнения определённой операции над множеством входящих данных. Например, это может быть считывание значения из памяти, затем прибавление его к другому значению, и наконец сохранение результата в память по другому адресу. Это может быть и нечто более сложное, например, деление двух чисел, если результат предыдущего вычисления больше нуля.

Программы, например, операционная система или игра, сами по себе являются последовательностями инструкций, которые должен выполнять ЦП. Эти инструкции загружаются из памяти и в простом процессоре выполняются одна за другой, пока программа не завершится. Разработчики программного обеспечения пишут программы на высокоуровневых языках, например, на C++ или на Python, но процессор не может их понимать. Он понимает только единицы и нули, поэтому нам нужно каким-то образом представить код в этом формате.


Программы компилируются в набор низкоуровневых инструкций, называемых языком ассемблера, который является частью архитектуры набора команд (Instruction Set Architecture, ISA). Это набор команд, которые должен понимать и выполнять ЦП. Одними из наиболее распространённых ISA являются x86, MIPS, ARM, RISC-V и PowerPC. Точно так же, как синтаксис написания функции на C++ отличается от функции, выполняющей то же действие в Python, у каждой ISA есть свой отличающийся синтаксис.

Эти ISA можно разбить на две основных категории: с фиксированной и с переменной длиной. ISA RISC-V использует инструкции с фиксированной длиной, и это означает, что определённое заранее заданное количество битов в каждой инструкции определяет, какой тип имеет эта инструкция. В x86 всё иначе, в нём используются инструкции с переменной длиной. В x86 инструкции могут кодироваться различным способом с разным количеством битов для разных частей. Из-за такой сложности декодер инструкций в процессоре x86 обычно является самой сложной частью всего устройства.

Инструкции с фиксированной длиной обеспечивают простое декодирование благодаря постоянной структуре, но ограничивают общее количество инструкций, которые могут поддерживаться ISA. В то время, как у популярных версий архитектуры RISC-V есть примерно 100 инструкций и все они имеют открытый исходный код, архитектура x86 проприетарна и никто не знает, сколько всего инструкций в ней есть. Обычно считается, что существует несколько тысяч инструкций x86, но точное число никто не публикует. Несмотря на различия между ISA, по сути все они имеют одинаковую базовую функциональность.


Пример некоторых инструкций RISC-V. Опкод справа имеет длину 7 бит и определяет тип инструкции. Кроме того, каждая инструкция содержит биты, определяющие используемые регистры и выполняемые функции. Так ассемблерные инструкции разбиваются на двоичный код, чтобы его понимал процессор.

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

Первый этап — передача инструкции из памяти в процессор для начала выполнения. На втором этапе инструкция декодируется, чтобы ЦП мог понять, какого типа эта инструкция. Существует множество типов, в том числе арифметические инструкции, инструкции ветвления и инструкции памяти. После того, как ЦП узнает, инструкцию какого типа он выполняет, операнды для инструкции берутся из памяти или внутренних регистров ЦП. Если вы хотите сложить число A и число B, то не можете выполнять сложение, пока не знаете значений A и B. Большинство современных процессоров являются 64-битными, то есть размер каждого значения данных составляет 64 бита.


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

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

Это объяснение, разумеется, сильно упрощено, и большинство современных процессоров для повышения эффективности разбивает эти несколько этапов на 20 или даже больше мелких этапов. Это означает, что хотя процессор начинает и завершает в каждом цикле несколько инструкций, может потребоваться 20 или больше циклов, чтобы выполнить одну инструкцию от начала до конца. Такая модель обычно называется pipeline («трубопровод», на русский обычно переводят как «конвейер»), потому что для заполнения трубопровода жидкостью и полного её прохождения требуется время, но после заполнения расход (вывод данных) будет постоянным.


Пример 4-этапного конвейера. Разноцветные прямоугольники обозначают независящие друг от друга инструкции.

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

Кроме выполнения с изменением очерёдности современные процессоры применяют технологию под названием суперскалярная архитектура. Это означает, что в любой момент времени процессор одновременно выполняет на каждом этапе конвейера множество инструкций. Он может также ожидать ещё сотни других, чтобы начать их выполнение, и для того, чтобы иметь возможность одновременного выполнения нескольких инструкций внутри процессоров есть несколько копий каждого этапа конвейера. Если процессор видит, что к выполнению готовы две инструкции, и между ними нет зависимости, то он не ждёт, пока они завершатся по отдельности, а выполняет их одновременно. Одна из популярных реализаций такой архитектуры называется Simultaneous Multithreading (SMT) и также известна, как Hyper-Threading. Процессоры Intel и AMD сейчас поддерживают двухсторонний SMT, а IBM разработала чипы, поддерживающие до восьми SMT.


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

Необходимость кэшей иногда может сбивать с толку, ведь они хранят данные, как и ОЗУ или SSD. Но кэши отличаются задержкой и скоростью доступа. Даже несмотря на то, что память ОЗУ чрезвычайно быстра, она на порядки величин медленнее, чем нужно для ЦП. Для ответа с передачей данных ОЗУ может потребоваться сотни циклов, и процессору в это время будет нечем заняться. А если данных нет в ОЗУ, то могут потребоваться десятки тысяч циклов для получения доступа к ним с SSD. Без кэшей процессоры бы постоянно стопорились.

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

Когда ЦП запрашивает данные из памяти, то сначала проверяет, хранятся ли эти данные уже в кэше L1. Если да, то можно всего за пару циклов получить к ним доступ. Если их там нет, то процессор проверяет L2, а затем и кэш L3. Кэши реализованы таким образом, что в общем случае они прозрачны для ядра. Ядро просто запрашивает данные по указанному адресу памяти, и тот уровень в иерархии, на котором они есть, отвечает ему. При переходе к последующим уровням в иерархии памяти размер и задержки обычно растут на порядки величин. В конце концов, если ЦП не находит данные ни в одном из кэшей, то обращается в основную память (ОЗУ).


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

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

Кроме кэшей одним из самых важных строительных блоков современного процессора является точный предсказатель переходов. Инструкции переходов (ветвлений) схожи с конструкциями «if» для процессора. Один набор инструкций выполняется, если условие истинно, а другой — если оно ложно. Например, нам нужно сравнить два числа, и если они равны, выполнить одну функцию, а если не равны, то выполнить другую. Эти инструкции ветвления применяются чрезвычайно часто и могут составлять примерно 20% всех инструкций в программе.

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

Чтобы обойти эту проблему, все современные высокопроизводительные процессоры используют методику под названием «упреждение» (speculation). Это означает, что процессор отслеживает инструкции ветвления и гадает, будет ли выполнен условный переход, или нет. Если предсказание верно, то процессор уже начал выполнять последующие инструкции, и это обеспечивает рост производительности. Если предсказание неверно, то процессор останавливает выполнение, удаляет все неверные инструкции, которые он начал выполнять, и начинает заново с правильной точки.

Такие предсказатели перехода — одни из самых простейших разновидностей машинного обучения, потому что предсказатель изучает поведение ветвей в процессе выполнения. Если он предсказывает неверно слишком часто, то начинает обучаться правильному поведению. Десятилетия исследований методик предсказания переходов привели к тому, что в современных процессорах точность предсказаний превышает 90%.

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

За последние десятилетия используемая в современных процессорах архитектура прошла долгий путь. Инновации и разработка продуманной структуры привели к повышению производительности и более оптимальному использованию аппаратных средств. Однако разработчики центральных процессоров тщательно хранят секреты их технологий, поэтому мы не можем точно узнать, что происходит у них внутри. Тем не менее, фундаментальные принципы работы процессоров стандартированы для всех архитектур и моделей. Intel может добавлять свои секретные ингредиенты, чтобы повысить долю попаданий кэша, а AMD может добавить улучшенный предсказатель переходов, но процессоры обеих компаний выполняют одинаковую задачу.

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

Рекомендуемое чтение

Как разрабатываются и производятся процессоры: проектирование ЦП / Хабр


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

Часть 1: Основы архитектуры компьютеров (архитектуры наборов команд, кэширование, конвейеры, hyperthreading)
Часть 2: Процесс проектирования ЦП (электрические схемы, транзисторы, логические элементы, синхронизация)
Часть 3: Компонование и физическое производство чипа (VLSI и изготовление кремния)
Часть 4: Современные тенденции и важные будущие направления в архитектуре компьютеров (море ускорителей, трёхмерное интегрирование, FPGA, Near Memory Computing)

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

Существует два основных типа транзисторов, используемых в современных процессорах: pMOS (PМОП) и nMOS (NМОП). nMOS-транзистор пропускает ток, когда затвор (gate) заряжен или имеет высокое напряжение, а pMOS-транзистор пропускает ток, когда затвор разряжен или имеет низкое напряжение. Сочетая эти типы транзисторов комплементарным образом, мы можем создавать логические элементы КМОП (CMOS). В этой статье мы не будем подробно разбирать особенности работы транзисторов, но коснёмся этого в третьей части серии.

Логический элемент — это простое устройство, получающее входные сигналы, выполняющее какую-то операцию, и выводящее результат. Например, элемент И (AND) включает свой выходной сигнал тогда и только тогда, когда включены все входы затвора. Инвертор, или элемент НЕ (NOT) включает свой выход, если вход отключён. Можно скомбинировать эти два затвора и получить элемент И-НЕ (NAND), который включает выход, тогда и только тогда, когда не включён ни один из входов. Существуют другие элементы со своей логической функциональностью, например ИЛИ (OR), ИЛИ-НЕ (NOR), исключающее ИЛИ (XOR) и исключающее ИЛИ с инверсией (XNOR).

Ниже показано, как из транзисторов собраны два простых элемента: инвертор и NAND. В инверторе pMOS-транзистор (сверху) соединён с питанием, а nMOS-транзистор (снизу) соединён с заземлением. На обозначении pMOS-транзисторов есть небольшой кружок, соединённый с затвором. Мы сказали, что pMOS-устройства пропускают ток, когда вход отключен, а nMOS-устройства пропускают ток, когда вход включен, поэтому легко заметить, что сигнал на выходе (Out) будет всегда противоположным сигналу на входе (In). Взглянув на элемент NAND, мы видим, что для него требуется четыре транзистора, и что выход всегда будет отключен, если выключен хотя бы один из входов. Соединение подобным образом транзисторов для образования простых сетей — это тот же процесс, который используется для проектирования более сложных логических элементов и других схем внутри процессоров.


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

В качестве небольшого примера давайте возьмём простой сумматор — 1-битный полный сумматор. Он получает три входных сигнала — A, B, и Carry-In (входной сигнал переноса), и создаёт два выходных сигнала — Sum (сумма) и Carry-Out (выходной сигнал переноса). В простейшей схеме используется пять логических элементов, и их можно соединить вместе для создания сумматора любого размера. В современных схемах этот процесс усовершенствован оптимизацией части логики и сигналов переноса, но фундаментальные основы остаются теми же.

Выход Sum равен или A, или B, но никогда обоим, или есть входящий сигнал переноса, и тогда A и B или оба включены, или оба выключены. Выходной сигнал переноса немного сложнее. Он активен, когда или A и B включены одновременно, или есть Carry-in и один из A или B включен. Чтобы соединить несколько 1-битных сумматоров для создания более широкого сумматора, нам просто нужно соединить Carry-out предыдущего бита с Carry-in текущего бита. Чем сложнее становятся схемы, тем запутанней получается логика, но это самый простой способ сложения двух чисел. В современных процессорах используются более изощрённые сумматоры, но их схемы слишком сложны для подобного обзора. Кроме сумматоров процессоры также содержат устройства для деления, умножения и версий всех этих операций с плавающей точкой.


Подобное объединение последовательностей элементов для выполнения некой функции над входными сигналами называется комбинаторной логикой. Однако это не единственный тип логики, используемый в компьютерах. Не будет особой пользы, если мы не сможем хранить данные или отслеживать состояние. Для того, чтобы иметь возможность сохранять данные, нам нужна секвенциальная логика.

Секвенциальная логика строится аккуратным соединением инверторов и других логических элементов так, чтобы их выходы передавали сигналы обратной связи на вход элементов. Такие контуры обратной связи используются для хранения одного бита данных и называются статическим ОЗУ (Static RAM), или SRAM. Эта память называется статическим ОЗУ в противовес динамической (DRAM), потому что сохраняемые данные всегда напрямую соединены с положительным напряжением или заземлением.

Стандартный способ реализации одного бита SRAM — это показанная ниже схема из 6 транзисторов. Самый верхний сигнал, помеченный как WL (Word Line) — это адрес, и когда он включен, то данные, хранящиеся в этой 1-битной ячейке передаются в Bit Line, помеченную как BL. Выход BLB называется Bit Line Bar; это просто инвертированное значение Bit Line. Вы должны узнать два типа транзисторов и понять, что M3 с M1, как и M4 с M2, образуют инвертор.


SRAM используется для построения сверхбыстрых кэшей и регистров внутри процессоров. Эта память очень стабильна, но для хранения каждого бита данных требует от шести до восьми транзисторов. Поэтому по сравнению с DRAM она чрезвычайно затратна с точки зрения стоимости, сложности и площади на чипе. С другой стороны, Dynamic RAM хранит данные в крошечном конденсаторе, а не использует логические элементы. Она называется динамической, потому что напряжение на конденсаторе может значительно изменяться, так как он не подключён к питанию или заземлению. Есть только один транзистор, используемый для доступа к хранящимся в конденсаторе данным.

Поскольку DRAM требует всего по одному транзистору на бит и очень масштабируема, её можно плотно и дёшево упаковывать. Недостаток DRAM заключается в том, что заряд конденсатора так мал, что его необходимо постоянно обновлять. Именно поэтому после отключения питания компьютера все конденсаторы разряжаются и данные в ОЗУ теряются.


Такие компании, как Intel, AMD и Nvidia, не публикуют схем работы своих процессоров, поэтому невозможно показать подобных полных электрических схем для современных процессоров. Однако этот простой сумматор позволит вам получить представление о том, что даже самые сложные части процессора можно разбить на логические и запоминающие элементы, а затем и на транзисторы.

Теперь, когда мы знаем, как производятся некоторые компоненты процессора, нам нужно разобраться, как соединить всё вместе и синхронизировать. Все ключевые компоненты процессора подключены к синхронизирующему (тактовому) сигналу (clock signal). Он попеременно имеет высокое и низкое напряжение, меняя его с заданным интервалом, называемым частотой (frequency). Логика внутри процессора обычно переключает значения и выполняет вычисления, когда синхронизирующий сигнал меняет напряжение с низкого на высокое. Синхронизируя все части, мы можем гарантировать, что данные всегда поступают в правильное время, чтобы в процессоре не возникали «глюки».

Вы могли слышать, что для повышения производительности процессора можно увеличить частоту тактовых сигналов. Это повышение производительности происходит благодаря тому, что переключение транзисторов и логики внутри процессора начинает происходить чаще, чем предусмотрено. Поскольку в секунду происходит больше циклов, то можно выполнить больше работы и процессор будет иметь повышенную производительность. Однако это справедливо до определённого предела. Современные процессоры обычно работают с частотой от 3,0 ГГц до 4,5 ГГц, и эта величина почти не изменилась за последние десять лет. Точно так же, как металлическая цепь не прочнее её самого слабого звена, процессор может работать не быстрее его самой медленной части. К концу каждого тактового цикла каждый элемент процессора должен завершить свою работу. Если какие-то части ещё её не завершили, то тактовый сигнал слишком быстрый и процессор не будет работать. Проектировщики называют эту самую медленную часть критическим путём (Critical Path) и именно он определяет максимальную частоту, с которой может работать процессор. Выше определённой частоты транзисторы просто не успевают достаточно быстро переключаться и начинают глючить или выдавать неверные выходные значения.

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

Подача питания — это настолько важная часть процессора, что в некоторых случаях до половины физических контактов на чипе может использоваться только для питания или заземления. Некоторые чипы при полной нагрузке могут потреблять больше 150 амперов, и со всем этим током нужно управляться чрезвычайно аккуратно. Для сравнения: центральный процессор генерирует больше тепла на единицу площади, чем ядерный реактор.

Тактовый сигнал в современных процессорах отнимает примерно 30-40% от его общей мощности, потому что он очень сложен и должен управлять множеством различных устройств. Для сохранения энергии большинство процессоров с низким потреблением отключает части чипа, когда они не используются. Это можно реализовать отключением тактового сигнала (этот способ называется Clock Gating) или отключением питания (Power Gating).

Тактовые сигналы создают ещё одну сложность при проектировании процессора: поскольку их частоты постоянно растут, то на работу начинают влиять законы физики. Даже несмотря на чрезвычайно высокую скорость света, она недостаточно велика для высокопроизводительных процессоров. Если подключить тактовый сигнал к одному концу чипа, то ко времени, когда сигнал достигнет другого конца, он будет рассинхронизован на значительную величину. Чтобы синхронизировать все части чипа, тактовый сигнал распределяется при помощи так называемого H-Tree. Это структура, гарантирующая, что все конечные точки находятся на совершенно одинаковом расстоянии от центра.


Может показаться, что проектирование каждого отдельного транзистора, тактового сигнала и контакта питания в чипе — чрезвычайно монотонная и сложная задача, и это в самом деле так. Даже несмотря на то, что в таких компаниях, как Intel, Qualcomm и AMD, работают тысячи инженеров, они не смогли бы вручную спроектировать каждый аспект чипа. Для проектирования чипов такого масштаба они используют множество сложных инструментов, автоматически генерирующих конструкции и электрические схемы. Такие инструменты обычно получают высокоуровневое описание того, что должен делать компонент, и определяют наилучшую аппаратную конфигурацию, удовлетворяющую этим требованиям. Недавно возникло направление развития под названием High Level Synthesis, которое позволяет разработчикам указывать необходимую функциональность в коде, после чего компьютеры определяют, как оптимальнее достичь её в оборудовании.

Точно так же, как вы можете описывать компьютерные программы через код, проектировщики могут описывать кодом аппаратные устройства. Такие языки, как Verilog и VHDL позволяют проектировщикам оборудования выражать функциональность любой создаваемой ими электрической схемы. После выполнения симуляций и верификации таких проектов их можно синтезировать в конкретные транзисторы, из которых будет состоять электрическая схема. Хоть этап верификации может и не кажется таким увлекательным, как проектирование нового кэша или ядра, он значительно важнее их. На каждого нанимаемого компанией инженера-проектировщика может приходиться пять или более инженеров по верификации.

Верификация нового проекта часто занимает больше времени и денег, чем создание самого чипа. Компании тратят так много времени и средств на верификацию, потому что после отправки чипа в производство его невозможно исправить. В случае ошибки в ПО можно выпустить патч, но оборудование работает иначе. Например, компания Intel обнаружила баг в модуле деления с плавающей запятой некоторых чипов Pentium, и в результате это вылилось в потери, эквивалентные современным 2 миллиардам долларов.

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

БОльшая часть работ по проектированию автоматизирована, но изложенное выше позволяет нам осознать, насколько сложен только что купленный нами новый ЦП.

Во второй части серии я рассказал о процессе проектирования ЦП. Мы обсудили транзисторы, логические элементы, подачу питания и синхронизирующих сигналов, синтез конструкции и верификацию. В третьей части мы узнаем, что требуется для физического производства чипа. Все компании любят хвастаться тем, насколько современен их процесс изготовления (Intel — 10-нанометровый, Apple и AMD — 7-нанометровый, и т.д.), но что же на самом деле означают эти числа? Об этом мы расскажем в следующей части.

Рекомендуемое чтение

будущее компьютерных архитектур / Хабр


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

Да, транзисторы стали меньше, чипы — быстрее, а производительность повысилась в сотни раз, но мы начинаем наблюдать стагнацию…

Это четвёртая и последняя часть серии статей о разработке ЦП, рассказывающей о проектировании и изготовлении процессоров. Начав с высокого уровня, мы узнали о том, как компьютерный код компилируется в язык ассемблера, а затем в двоичные инструкции, которые интерпретирует ЦП. Мы обсудили то, как проектируется архитектура процессоров и они обрабатывают инструкции. Затем мы рассмотрели различные структуры, из которых составлен процессор.

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

Часть 1: Основы архитектуры компьютеров (архитектуры наборов команд, кэширование, конвейеры, hyperthreading)
Часть 2: Процесс проектирования ЦП (электрические схемы, транзисторы, логические элементы, синхронизация)
Часть 3: Компонование и физическое производство чипа (VLSI и изготовление кремния)
Часть 4: Современные тенденции и важные будущие направления в архитектуре компьютеров (море ускорителей, трёхмерное интегрирование, FPGA, Near Memory Computing)

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

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


Закон Мура на протяжении 120 лет. Этот график становится ещё интереснее, если узнать, что последние 7 точек относятся к GPU компании Nvidia, а не к процессорам общего назначения. Иллюстрация Стива Джарветсона

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

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


Один из прототипов квантовых компьютеров IBM

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

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

Нарастает тенденция влияния гетерогенных вычислений. Эта методика заключается во включении в одну систему множества различных вычислительных элементов. Большинство из нас пользуется преимуществами такого подхода в виде отдельных GPU в компьютерах. Центральный процессор очень гибок и может с приличной скоростью выполнять широкий диапазон вычислительных задач. С другой стороны, GPU спроектированы специально для выполнения графических вычислений, например, перемножения матриц. Они очень хорошо с этим справляются и на порядки величин быстрее ЦП в подобных видах инструкций. Перенеся часть графических вычислений с ЦП на GPU, мы можем ускорить расчёты. Любой программист может оптимизировать ПО, изменив алгоритм, но оптимизировать оборудование гораздо сложнее.

Но GPU — не единственная область, в которой акселераторы становятся всё популярнее. В большинстве смартфонов есть десятки аппаратных акселераторов, предназначенных для ускорения очень специфических задач. Такой стиль вычислений называется морем акселераторов (Sea of Accelerators), его примерами могут быть криптографические процессоры, процессоры изображений, ускорители машинного обучения, кодеры/декодеры видео, биометрические процессоры и многое другое.

Нагрузки становятся всё более и более специализированными, поэтому проектировщики включают в свои чипы всё больше акселераторов. Поставщики облачных услуг, например AWS, начали предоставлять разработчикам FPGA-карты для ускорения их вычислений в облаках. В отличие от традиционных вычислительных элементов наподобие ЦП и GPU, имеющих фиксированную внутреннюю архитектуру, FPGA гибки. Это почти программируемое оборудование, которое можно настраивать в соответствии с нуждами компании.

Если кому-то нужно распознавание изображений, то он реализует эти алгоритмы в «железе». Если кто-то хочет симулировать работу новой аппаратной архитектуры, то перед изготовлением её можно протестировать на FPGA. FPGA обеспечивает бОльшую производительность и энергоэффективность, чем GPU, но всё равно меньше, чем у ASIC (application specific integrated circuit — интегральная схема специального назначения). Другие компании, например, Google и Nvidia, разрабатывают отдельные ASIC машинного обучения для ускорения распознавания и анализа изображений.


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

Взглянув на снимки кристаллов относительно современных процессоров, можно увидеть, что бОльшую часть площади ЦП на самом деле занимает не само ядро. Всё бОльшую долю занимают различные акселераторы. Это позволило ускорить очень специализированные вычисления, а также значительно снизить энергопотребление.

Раньше при необходимости добавления в систему обработки видео разработчикам приходилось устанавливать в неё новый чип. Однако это очень неэффективно с точки зрения энергопотребления. Каждый раз, когда сигналу нужно выходить из чипа по физическому проводнику к другому чипу, на бит требуется огромное количество энергии. Сама по себе крошечная доля джоуля не кажется особо большими тратами, но передача данных внутри, а не снаружи чипа может быть на 3-4 порядка величин эффективнее. Благодаря интеграции таких акселераторов с ЦП мы наблюдали в последнее время рост количества чипов с сверхнизким энергопотреблением.

Однако акселераторы не идеальны. Чем больше мы добавляем их в схемы, тем менее гибким становится чип и мы начинаем жертвовать общей производительностью в пользу пиковой производительности специализированных видов вычислений. На каком-то этапе весь чип просто превращается в набор акселераторов и перестаёт быть полезным ЦП. Баланс между производительностью специализированных вычислений и общей производительностью всегда очень тщательно настраивается. Это разногласие между оборудованием общего назначения и специализированными нагрузками называется разрывом специализации (specialization gap).

Хотя кое-кто считает. что мы находимся на пике пузыря GPU/Machine Learning, скорее всего стоит ожидать, что всё больший объём вычислений будет передаваться специализированным ускорителям. Облачные вычисления и ИИ продолжают развиваться, поэтому GPU выглядят лучшим решением для достижения уровня требуемых объёмных вычислений.

Ещё одна область, в которой проектировщики ищут способы повышения производительности — это память. Традиционно считывание и запись значений всегда были одним из самых серьёзных «узких мест» процессоров. Нам могут помочь быстрые и большие кэши, но считывание из ОЗУ или с SSD может занимать десятки тысяч тактовых циклов. Поэтому инженеры часто рассматривают доступ к памяти как более затратный, чем сами вычисления. Если процессор хочет сложить два числа, то ему сначала нужно вычислить адреса памяти, по которым хранятся числа, выяснить, на каком уровне иерархии памяти есть эти данные, считать данные в регистры, выполнить вычисления, вычислить адрес приёмника и записать значение в нужное место. Для простых инструкций, выполнение которых может занимать один-два цикла, это чрезвычайно неэффективно.

Новая идея, которую сейчас активно исследуют — это техника под названием Near Memory Computing. Вместо того, чтобы извлекать небольшие фрагменты данных из памяти и вычислять их быстрым процессором, исследователи переворачивают работу вниз головой. Они экспериментируют с созданием небольших процессоров непосредственно в контроллерах памяти ОЗУ или SSD. Благодаря тому, что вычисления становятся ближе к памяти, существует потенциал огромной экономии энергии и времени, ведь данные теперь не надо передавать так часто. Вычислительные модули имеют прямой доступ к нужным им данным, потому что находятся непосредственно в памяти. Эта идея всё ещё находится в зачаточном состоянии, но результаты выглядят многообещающе.

Одно из препятствий, которое нужно преодолеть для near memory computing — это ограничения процесса изготовления. Как говорилось в третьей части, процесс производства кремния очень сложен и в нём задействованы десятки этапов. Эти процессы обычно специализированы для изготовления или быстрых логических элементов, или плотно расположенных накопительных элементов. Если попытаться создать чип памяти с помощью оптимизированного для вычислений процесса изготовления, то получится чип с чрезвычайно низкой плотностью элементов. Если попробовать создать процессор с помощью процесса изготовления накопителей, то получим очень низкую производительность и большие тайминги.


Пример 3D-интеграции, демонстрирующий вертикальные соединения между слоями транзисторов.

Одно из потенциальных решений этой проблемы — 3D-интеграция. Традиционные процессоры обладают одним очень широким слоем транзисторов, но это имеет свои ограничения. Как понятно из названия, трёхмерная интеграция — это процесс расположения нескольких слоёв транзисторов друг над другом для повышения плотности и снижения задержек. Вертикальные столбцы, производимые на разных процессах изготовления, могут быть затем использованы для соединений между слоями. Эта идея была предложена уже давно, но индустрия потеряла к ней интерес из-за серьёзных сложностей в её реализации. В последнее время мы наблюдаем возникновение технологии накопителей 3D NAND и возрождение этой области исследований.

Кроме физических и архитектурных изменений, на всю полупроводниковую отрасль сильно повлияет ещё одна тенденция — больший упор на безопасность. До недавнего времени о безопасности процессоров думали чуть ли не в последний момент. Это похоже на то, как Интернет, электронная почта и многие другие системы, которые мы сегодня активно используем, разрабатывались почти без оглядки на безопасность. Все существующие меры защиты «прикручивались» по мере случавшихся инцидентов, чтобы мы чувствовали себя в безопасности. В области процессоров такая тактика больно ударила по компаниям, и особенно по Intel.

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

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

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

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

Из чего состоит центральный процессор? — i2HARD

Статьи • 1 Мая 2020 • Sannio

Центральный процессор часто называют «мозгом» компьютера, ведь он, как и человеческий мозг, состоит из нескольких частей, собранных воедино для работы над информацией. Среди них есть те, что отвечают за прием информации, ее хранение, обработку и вывод. В этой статье портал TechSpot разбирает все ключевые элементы процессора, за счет которых и работают ваши компьютеры.

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

В этой статье будут затронуты как основы работы процессоров, так и более сложные понятия. К сожалению, без некоторой абстрактности не обойтись, но на это есть свои причины. К примеру, если взглянуть на блок питания, можно легко рассмотреть все его части — от конденсаторов до транзисторов, однако в случае с процессорами все не так просто, ведь мы физически не можем разглядеть все микросхемы, а Intel и AMD не спешат делиться подробностями работы своей продукции с широкой публикой. Тем не менее, информация, представленная в статье, применима к подавляющему большинству современных процессоров. 

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

Фундамент любого процессора: архитектура набора команд

Первое, на что натыкаешься при разборе любого процессора — это на архитектуру набора команд (ISA). Архитектура является чем-то вроде фундамента работы процессора и именно от нее зависит то, как он работает и как все внутренние системы взаимодействуют друг с другом. Существует огромное количество архитектур, но самыми распространенными являются x86 (преимущественно в стационарных компьютерах и ноутбуках) и ARM (в мобильных устройствах и встроенных системах).  

Чуть менее распространенными и более нишевыми являются MIPS, RISC-V и PowerPC. Архитектура набора отвечает за ряд основных вещей: какие инструкции процессор может обрабатывать, как он взаимодействует с памятью и кэшем, как задача распределяется по нескольким этапам обработки и др.  

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

Блок управления и исполнительный тракт

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

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

Блок-схема работы базового процессора. Черными линиями отображен поток данных, а красными — поток команд.

Цикл выполнения команд — Выборка

Первое, что должен сделать процессор — определить, какие команды необходимо выполнить следующими, а затем переместить их из памяти в блок управления. Команды создаются компилятором и зависят от архитектуры набора (ISA). Наиболее распространенные типы базовых инструкций (например, «загрузка», «хранение», «сложение», «вычитание» и др.) общие для всех ISA, но существует множество дополнительных, специальных типов команд, уникальных для конкретной архитектуры набора. Блок управления знает, какие сигналы и куда нужно направить для выполнения определенного типа команды.

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

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

Цикл выполнения команд — Декодирование

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

конец 80-х — начало 2000-х / Блог компании ua-hosting.company / Хабр

Продолжая тему первой статьи — история эволюции процессоров с конца XX века по начала XXI века.

Во многих процессорах 80-х годов использовалась архитектура CISC (Complex instruction set computing). Чипы были довольно сложными и дорогими, а также не достаточно производительными. Возникла необходимость в модернизации производства и увеличения количества транзисторов.

Архитектура RISC

В 1980 году стартовал проект Berkeley RISC, которым руководили американские инженеры Дэвид Паттерсон и Карло Секвин. RISC (restricted instruction set computer) — архитектура процессора с увеличенным быстродействием благодаря упрощенным инструкциям.

Руководители проекта Berkeley RISC — Дэвид Паттерсон и Карло Секвин

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

RISC I вышел в 1982 году и содержал более чем 44 420 транзисторов. Он имел всего 32 инструкции и работал на частоте 4 МГц. Следующий за ним RISC II насчитывал 40 760 транзисторов, использовал 39 инструкций и был более быстрым.

Процессор RISC II

Процессоры MIPS: R2000, R3000, R4000 и R4400

Архитектура процессоров MIPS (Microprocessor without Interlocked Pipeline Stages) предусматривала наличие вспомогательных блоков в составе кристалла. В MIPS использовался удлиненный конвейер.

В 1984 году группа исследователей во главе с американским ученым Джоном Хеннесси основала компанию, проектирующую микроэлектронные устройства. MIPS лицензировала микропроцессорную архитектуру и IP-ядра для устройств умного дома, сетевых и мобильных применений. В 1985 году вышел первый продукт компании — 32-битный R2000, который в 1988 году был доработан в R3000. У обновленной модели имелась поддержка многопроцессорности, кэш-памяти инструкций и данных. Процессор нашел применение в SG-сериях рабочих станций разных компаний. Также R3000 стал основой игровой консоли Sony PlayStation.

Процессор R3000

В 1991 году вышла линейка нового поколения R4000. Данный процессор обладал 64-битной архитектурой, встроенным сопроцессором и работал на тактовой частоте 100 МГц. Внутренняя кэш-память составляла 16 Кб (8 Кб кэш-команд и 8 Кб кэш-данных).

Через год вышла доработанная версия процессора — R4400. В этой модели увеличился кэш до 32 Кб (16 Кб кэш-команд и 16 Кб кэш-данных). Процессор мог работать на частоте 100 МГц — 250 МГц.

Процессоры MIPS: R8000 и R10000

В 1994 году появился первый процессор с суперскалярной реализацией архитектуры MIPS — R8000. Емкость кэш-памяти данных составляла 16 Кб. У этого CPU была высокая пропускная способность доступа к данным (до 1.2 Гб/с) в сочетании с высокой скоростью выполнения операций. Частота достигала 75 МГц — 90 МГц. Использовалось 6 схем: устройство для целочисленных команд, для команд с плавающей запятой, три вторичных дескриптора кэш-памяти ОЗУ и кэш-контроллер ASIC.

Процессор R8000

В 1996 году вышла доработанная версия — R10000. Процессор включал в себя 32 Кб первичной кэш-памяти данных и команд. Работал CPU на частоте 150 МГц — 250 МГц.

В конце 90-х компания MIPS занялась продажей лицензий на 32-битную и 64-битную архитектуры MIPS32 и MIPS64.

Процессоры SPARC

Ряды процессоров пополнили продукты компании Sun Microsystems, которая разработала масштабируемую архитектуру SPARC (Scalable Processor ARChitecture). Первый одноименный процессор вышел в конце 80-х и получил название SPARC V7. Его частота достигала 14.28 МГц — 40 МГц.

В 1992 году появилась следующая 32-битная версия под названием SPARC V8, на базе которой был создан процессор microSPARC. Тактовая частота составляла 40 МГц — 50 МГц.

Над созданием следующего поколения архитектуры SPARC V9 с компанией Sun Microsystems совместно работали Texas Instruments, Fujitsu, Philips и другие. Платформа расширилась до 64 бит и являлась суперскалярной с 9-стадийным конвейером. SPARC V9 предусматривала использование кэш-памяти первого уровня, разделенного на инструкции и данные (каждая объемом по 16 Кб), а также второго уровня емкостью 512 Кб — 1024 Кб.

Процессор UltraSPARC III

Процессоры StrongARM

В 1995 году стартовал проект по разработке семейства микропроцессоров StrongARM, реализовавших набор инструкций ARM V4. Эти CPU представляли собой классическую скалярную архитектуру с 5-стадийным конвейером, включая блоки управления памятью и поддерживая кэш-память инструкций и данных объемом по 16 Кб каждая.

StrongARM SA-110

И уже в 1996 году был выпущен первый процессор на базе StrongARM — SA-110. Он работал на тактовых частотах 100 МГц, 160 МГц или 200 МГц.

Также на рынок вышли модели SA-1100, SA-1110 и SA-1500.

Процессор SA-110 в Apple MessagePad 2000

Процессоры POWER, POWER2 и PowerPC

В 1985 году компания IBM начала разработку RISC-архитектуры следующего поколения в рамках проекта America Project. Разработка процессора POWER (Performance Optimization With Enhanced RISC) и набора инструкций для него длилась 5 лет. Он был весьма производительный, но состоял из 11 различных микросхем. И поэтому в 1992 году вышел другой вариант процессора, что умещался в одном чипе.

Чипсет POWER

В 1991 году совместными усилиями альянса компаний IBM, Apple и Motorola была разработана архитектура PowerPC (сокращенно PPC). Она состояла из базового набора функций платформы POWER, а также поддерживала работу в двух режимах и была обратно совместима с 32-битным режимом работы для 64-разрядной версии. Основным назначением являлись персональные компьютеры.

Процессор PowerPC 601 использовался в Macintosh.

Процессор PowerPC

В 1993 году был представлен POWER2 с расширенным набором команд. Тактовая частота процессора варьировалась от 55 МГц до 71.5 МГц, а кэш-память данных и инструкций была 128-256 Кб и 32 Кб. Микросхемы процессора (их было 8) содержали 23 миллиона транзисторов, а изготавливался он по 0.72-микрометровой CMOS-технологии.

В 1998 году IBM выпустила третью серию процессоров POWER3 на 64 бита, полностью совместимых со стандартом PowerPC.

В период с 2001 по 2010 вышли модели POWER4 (до восьми параллельно выполняющихся команд), двухядерные POWER5 и POWER6, четырех-восьми ядерный POWER7.

Процессоры Alpha 21064A

В 1992 году компания Digital Equipment Corporation (DEC) выпустила процессор Alpha 21064 (EV4). Это был 64-разрядный суперскалярный кристалл с конвейерной архитектурой и тактовой частотой 100 МГц — 200 МГц. Изготовлен по 0,75-мкм техпроцессу, со внешней 128-разрядной шиной процессора. Присутствовало 16 Кб кэш-памяти (8 Кб данных и 8 Кб инструкций).

Следующей моделью в серии стал процессор 21164 (EV5), который вышел в 1995 году. Он обладал двумя целочисленными блоками и насчитывал уже три уровня кэш-памяти (два в процессоре, третий — внешний). Кэш-память первого уровня разделялась на кэш данных и кэш инструкций объемом по 8 Кб каждый. Объем кэш-памяти второго уровня составлял 96 Кб. Тактовая частота процессора варьировалась от 266 МГц до 500 МГц.

DEC Alpha AXP 21064

В 1996 году вышли процессоры Alpha 21264 (EV6) с 15,2 миллионами транзисторов, изготовленные по 15,2-мкм техпроцессу. Их тактовая частота составляла от 450 МГц до 600 МГц. Целочисленные блоки и блоки загрузки/сохранения были объединены в единый модуль Ebox, а блоки вычислений с плавающей запятой — в модуль Fbox. Кэш первого уровня сохранил разделение на память для инструкций и для данных. Объем каждой части составлял 64 Кб. Объем кэш-памяти второго уровня был от 2 Мб до 8 Мб.

В 1999 году DEC купила компания Compaq. В результате чего большая часть производства продукции, использовавшей Alpha, была передана компании API NetWorks, Inc.

Процессоры Intel P5 и P54C

По макету Винода Дхама был разработан процессор пятого поколения под кодовым названием P5. В 1993 году CPU вышли в производство под названием Pentium.

Процессоры на ядре P5 производились с использованием 800-нанометрового техпроцесса по биполярной BiCMOS-технологии. Они содержали 3,1 миллиона транзисторов. У Pentium была 64-битная шина данных, суперскалярная архитектура. Имелось раздельное кэширование программного кода и данных. Использовалась кэш-память первого уровня объемом 16 Кб, разделенная на 2 сегмента (8 Кб для данных и 8 Кб для инструкций). Первые модели были с частотами 60 МГц — 66 МГц.

Процессор Intel Pentium

В том же году Intel запустила в продажу процессоры P54C. Производство новых процессоров было переведено на 0,6-мкм техпроцесс. Скорость работы процессоров составляла 75 МГц, а с 1994 года — 90 МГц и 100 МГц. Через год архитектура P54C (P54CS) была переведена на 350-нм техпроцесс и тактовая частота увеличилась до 200 МГц.

В 1997 году P5 получила последнее обновление — P55C (Pentium MMX). Появилась поддержка набора команд MMX (MultiMedia eXtension). Процессор состоял из 4,5 миллиона транзисторов и производится по усовершенствованной 280-нанометровой CMOS-технологии. Объем кэш-памяти первого уровня увеличился до 32 Кб (16 Кб для данных и 16 Кб для инструкций). Частота процессора достигла 233 МГц.

Процессоры AMD K5 и K6

В 1995 году компания AMD выпустила процессор K5. Архитектура представляла собой RISC-ядро, но работала со сложными CISC-инструкциями. Процессоры изготавливались с использованием 350- или 500-нанометрового техпроцесса, с 4,3 миллионами транзисторов. Все K5 имели пять целочисленных блоков и один блок вычислений с плавающей запятой. Объем кэш-памяти инструкций составлял 16 Кб, а данных — 8 Кб. Тактовая частота процессоров варьировалась от 75 МГц до 133 МГц.

Процессор AMD K5

Под маркой K5 выпускалось два варианта процессоров SSA/5 и 5k86. Первый работал на частотах от 75 МГц до 100 МГц. Процессор 5k86 работал на частотах от 90 МГц до 133 МГц.

В 1997 году компания представила процессор K6, архитектура которого существенно отличалась от K5. Процессоры изготавливались по 350-нанометровому техпроцессу, включали в себя 8,8 миллионов транзисторов, поддерживали изменение порядка выполнения инструкций, набор команд MMX и блок вычислений с плавающей запятой. Площадь кристалла составляла 162 мм². Объем кэш-памяти первого уровня насчитывал 64 Кб (32 Кб данные и 32 Кб инструкции). Работал процессор на частоте 166 МГц, 200 МГц и 233 МГц. Частота системной шины была 66 МГц.

В 1998 году AMD выпустила чипы с улучшенной архитектурой K6-2, с 9,3 миллионами транзисторов изготавливаемого по 250-нанометровому техпроцессу. Максимальная частота чипа составляла 550 МГц.

Процессор AMD K6

В 1999 году вышла третья генерация — архитектура K6-III. Кристалл сохранил все особенности K6-2, но при этом появилась встроенная кэш-память второго уровня объемом 256 Кб. Объем кэша первого уровня составлял 64 Кб.

Процессоры AMD K7

В том же 1999 году на смену К6 пришли процессоры К7. Они выпускались по 250-нм технологии с 22 миллионами транзисторов. У CPU присутствовал новый блок целочисленных вычислений (ALU). Системная шина EV6 обеспечивала передачу данных по обоим фронтам тактового сигнала, что давало возможность при физической частоте 100 МГц получить эффективную частоту 200 МГц. Объем кэш-памяти первого уровня составлял 128 Кб (64 Кб инструкций и 64 Кб данных). Кэш второго уровня достигал 512 Кб.

Процессор AMD K7

Несколько позже появились кристаллы, базировавшиеся на ядре Orion. Они производилось по 180-нм техпроцессу.

Выход ядра Thunderbird внес необычные изменения в процессоры. Кэш-память 2-го уровня была перенесена непосредственно в процессорное ядро и работала на одинаковой с ним частоте. Кэш был с эффективным объемом 384 Кб (128 Кб кэша первого уровня и 256 Кб кэша второго уровня). Увеличилась тактовая частота системной шины — теперь она функционировала с частотой 133 МГц.

Процессоры Intel P6

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

В том же 1995 году были представлены процессоры следующего поколения Pentium Pro. Кристаллы работали на частоте 150 МГц — 200 МГц, имели 16 Кб кэш-памяти первого уровня и до 1 Мб кэша второго уровня.

Процессор Intel Pentium Pro

В 1999 году были представлены первые процессоры Pentium III. Они базировались на новой генерации ядра P6 под названием Katmai, которые являлись модифицированными версиями Deschutes. В ядро была добавлена поддержка инструкций SSE, а также улучшился механизм работы с памятью. Тактовая частота процессоров Katmai достигала 600 МГц.

В 2000 году вышли первые процессоры Pentium 4 с ядром Willamette. Эффективная частота системной шины составляла 400 МГц (физическая частота — 100 МГц). Кэш-данных первого уровня достигал объема 8 Кб, а кэш-память второго уровня — 256 Кб.

Следующим ядром линейки стало Northwood (2002 год). Процессоры содержали 55 миллионов транзисторов и производились по новой 130-нм КМОП-технологии с медными соединениями. Частота системной шины составляла 400 МГц, 533 МГц или 800 МГц.

Intel Pentium 4

В 2004 году производство процессоров вновь перевели на более тонкие технологические нормы — 90 нм. Вышли Pentium 4 на ядре Prescott. Кэш данных первого уровня увеличился до 16 Кб, а кэш второго уровня достиг 1 Мб. Тактовая частота составляла 2,4 ГГц — 3,8 ГГц, частота системной шины — 533 МГц или 800 МГц.

Последним ядром, которое использовалось в процессорах Pentium 4 стало одноядерное Cedar Mill. Выпускалось по новому техпроцессу — 65 нм. Существовало четыре модели: 631 (3 ГГц), 641 (3,2 ГГц), 651 (3,4 ГГц), 661 (3,6 ГГц).

Процессоры Athlon 64 и Athlon 64 X2

В конце 2003 года AMD выпустила новую 64-битную архитектуру K8, построенную по 130-нанометровому техпроцессу. В процессоре был встроенный контроллер памяти и шина HyperTransport. Она работала на частоте 200 МГц. Новые продукты AMD получили название Athlon 64. Процессоры поддерживали множество наборов команд, таких как MMX, 3DNow!, SSE, SSE2 и SSE3.

Процессор Athlon 64

В 2005 году на рынок вышли процессоры компании AMD под названием Athlon 64 X2. Это были первые двухъядерные процессоры для настольных компьютеров. В основе модели лежали два ядра, выполненных на одном кристалле. Они имели общий контроллер памяти, шину HyperTransport и очередь команд.

Процессор Athlon 64 X2

В течение 2005 и 2006 годов AMD выпустила четыре поколения двухъядерных чипов: три 90-нм ядра Manchester, Toledo и Windsor, а также 65-нм ядро Brisbane. Процессоры отличались объемом кэш-памяти второго уровня и энергопотреблением.

Процессоры Intel Core

Процессоры Pentium M обеспечивали большую производительность, чем настольные процессоры на базе микроархитектуры NetBurst. И поэтому их архитектурные решения стали основой для микроархитектуры Core, которая вышла в 2006 году. Первым настольным четырехядерным процессором стал Intel Core 2 Extreme QX6700 с тактовой частотой 2.67 ГГц и 8 Мб кэш-памяти второго уровня.

Кодовое имя первого поколения мобильных процессоров компании Intel было Yonah. Они производились с использованием техпроцесса 65 нм, основанного на архитектуре Banias/Dothan Pentium M, с добавленной технологией защиты LaGrande. Процессор мог обрабатывать до четырех инструкций за такт. В Core был переработан алгоритм обработки 128-битных инструкций SSE, SSE2 и SSE3. Если раньше каждая команда обрабатывалась за два такта, то теперь для операции требовался лишь один такт.

Intel Core 2 Extreme QX6700

В 2007 году вышла 45-нм микроархитектура Penryn с использованием металлических затворов Hi-k без содержания свинца. Технология использовалась в семействе процессоров Intel Core 2 Duo. В архитектуру добавилась поддержка инструкций SSE4, а максимальный объем кэш-памяти 2-го уровня у двухъядерных процессоров увеличился с 4 Мб до 6 Мб.

Процессор AMD Phenom II X6

В 2008 году вышла архитектура следующего поколения — Nehalem. Процессоры обзавелись встроенным контроллером памяти, поддерживающим 2 или 3 канала DDR3 SDRAM или 4 канала FB-DIMM. На смену шине FSB, пришла новая шина QPI. Объем кэш-памяти 2-го уровня уменьшился до 256 Кб на каждое ядро.

Intel Core i7

Вскоре Intel перевела архитектуру Nehalem на новый 32-нм техпроцесс. Эта линейка процессоров получила название Westmere.
Первой моделью новой микроархитектуры стал Clarkdale, обладающий двумя ядрами и интегрированным графическим ядром, производимым по 45-нм техпроцессу.

Процессоры AMD K10

Компания AMD старалась не отставать от Intel. В 2007 году она выпустила поколение архитектуры микропроцессоров x86 — K10. Четыре ядра процессора были объединены на одном кристалле. В дополнение к кэшу 1-го и 2-го уровней модели K10 наконец получили L3 объемом 2 Мб. Объем кэша данных и инструкций 1-го уровня составлял 64 Кб каждый, а кэш-памяти 2-го уровня — 512 Кб. Также появилась перспективная поддержка контроллером памяти DDR3. В K10 использовалось два 64-битных контроллера. Каждое процессорное ядро имело 128-битный модуль вычислений с плавающей запятой. Вдобавок ко всему, новые процессоры работали через интерфейс HyperTransport 3.0.

В 2007 году с архитектурой K10 вышли многоядерные центральные процессоры Phenom фирмы AMD, предназначенные для использования в стационарных персональных компьютерах. Решения на базе K10 производились по 65- и 45-нм техпроцессу. В новой версии архитектуры (К10,5) контроллер памяти работал с памятью DDR2 и DDR3.

Процессор AMD Phenom

В 2011 году вышла новая архитектура Bulldozer. Каждый модуль содержал два ядра со своим блоком целочисленных вычислений и кэш-памятью 1-го уровня. Поддерживалась кэш-память 3-го уровня объемом 8 Мб, шины HyperTransport 3.1, технологии увеличения частоты ядер Turbo Core второго поколения и наборов инструкций AVX, SSE 4.1, SSE 4.2, AES. Также процессоры Bulldozer были наделены двухканальным контроллером памяти DDR3 с эффективной частотой 1866 МГц.

Процессор AMD Bulldozer

В 2013 году компания представила следующее поколение процессоров — Piledriver. Данная модель являлась улучшенной архитектурой Bulldozer. Были доработаны блоки предсказания ветвлений, возросла производительность модуля операций с плавающей запятой и целочисленных вычислений, а также тактовая частота.

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

Как проектируются и строятся процессоры

Мы все думаем о ЦП как о «мозге» компьютера, но что это на самом деле означает? Что происходит внутри миллиардов транзисторов, которые заставляют ваш компьютер работать? В этой мини-серии из четырех частей мы сосредоточимся на дизайне компьютерного оборудования, охватывая все тонкости того, что заставляет компьютер работать.

Серия

будет охватывать архитектуру компьютеров, проектирование схем процессоров, СБИС (очень крупномасштабную интеграцию), изготовление микросхем и будущие тенденции в вычислительной технике.Если вас всегда интересовали детали того, как процессоры работают внутри, оставайтесь здесь, потому что это то, что вы хотите знать, чтобы начать работу.

Мы начнем с очень высокого уровня того, что делает процессор и как строительные блоки объединяются в функциональную конструкцию. Сюда входят ядра процессора, иерархия памяти, предсказание ветвлений и многое другое. Во-первых, нам нужно базовое определение того, что делает ЦП. Самое простое объяснение состоит в том, что ЦП следует набору инструкций для выполнения некоторой операции с набором входов.Например, это может быть чтение значения из памяти, затем добавление его к другому значению и, наконец, сохранение результата обратно в память в другом месте. Это также может быть что-то более сложное, например деление двух чисел, если результат предыдущего вычисления был больше нуля.

Когда вы хотите запустить программу, например операционную систему или игру, сама программа представляет собой серию инструкций, которые должен выполнять ЦП. Эти инструкции загружаются из памяти и на простом процессоре выполняются одна за другой, пока программа не будет завершена.Хотя разработчики программного обеспечения пишут свои программы на языках высокого уровня, таких как, например, C ++ или Python, процессор не может этого понять. Он понимает только единицы и нули, поэтому нам нужен способ представления кода в этом формате.

Программы компилируются в набор низкоуровневых инструкций, называемых языком ассемблера , как часть архитектуры набора команд (ISA). Это набор инструкций, которые ЦП создан для понимания и выполнения. Некоторые из наиболее распространенных ISA — это x86, MIPS, ARM, RISC-V и PowerPC.Так же, как синтаксис для написания функции в C ++ отличается от функции, которая делает то же самое в Python, каждый ISA имеет другой синтаксис.

Эти ISA можно разделить на две основные категории: фиксированной и переменной длины. RISC-V ISA использует инструкции фиксированной длины, что означает, что определенное заранее определенное количество бит в каждой инструкции определяет, какой это тип инструкции. Это отличается от x86, в котором используются инструкции переменной длины. В x86 инструкции можно кодировать по-разному и с разным количеством бит для разных частей.Из-за этой сложности декодер команд в процессорах x86 обычно является наиболее сложной частью всей конструкции.

Инструкции фиксированной длины позволяют упростить декодирование из-за их регулярной структуры, но ограничивают общее количество инструкций, которые может поддерживать ISA. В то время как обычные версии архитектуры RISC-V содержат около 100 инструкций и имеют открытый исходный код, x86 является проприетарной, и никто точно не знает, сколько там инструкций. Обычно люди считают, что существует несколько тысяч инструкций x86, но точное количество не известно.Несмотря на различия между ISA, все они несут по существу одинаковые основные функции.

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

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

Первым шагом является выборка инструкции из памяти в ЦП для начала выполнения. На втором этапе инструкция декодируется, чтобы ЦП мог определить, какой это тип инструкции. Есть много типов, включая арифметические инструкции, инструкции перехода и инструкции памяти. Как только CPU знает, какой тип инструкции он выполняет, операнды для инструкции собираются из памяти или внутренних регистров в CPU.Если вы хотите добавить число A к числу B, вы не можете выполнить сложение, пока не узнаете значения A и B. Большинство современных процессоров 64-битные, что означает, что размер каждого значения данных составляет 64 бита.

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

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

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

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

.

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

В дополнение к выполнению вне очереди, типичные современные процессоры используют так называемую суперскалярную архитектуру . Это означает, что в любой момент процессор выполняет множество инструкций одновременно на каждом этапе конвейера.Он также может ждать, когда начнутся казни еще сотни. Чтобы иметь возможность выполнять множество инструкций одновременно, процессоры должны иметь внутри несколько копий каждой стадии конвейера. Если процессор видит, что две инструкции готовы к выполнению и между ними нет зависимости, вместо того, чтобы ждать их завершения по отдельности, он выполнит их обе одновременно. Одна из распространенных реализаций этого называется одновременной многопоточностью (SMT), также известной как Hyper-Threading.Процессоры Intel и AMD в настоящее время поддерживают двусторонний SMT, в то время как IBM разработала микросхемы, которые поддерживают до восьми процессоров SMT.

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

Назначение кэшей часто может сбивать с толку, поскольку они хранят данные точно так же, как RAM или SSD. Что отличает кеши, так это их задержка доступа и скорость. Несмотря на то, что оперативная память очень быстрая, она на несколько порядков медленнее для процессора. ОЗУ может потребовать сотни циклов, чтобы ответить с данными, и процессор зависнет, нечего делать. Если данных нет в ОЗУ, доступ к данным на SSD может занять десятки тысяч циклов. Без кешей наши процессоры остановились бы.

Процессоры

обычно имеют три уровня кеш-памяти, которые образуют так называемую иерархию памяти . Кэш L1 самый маленький и самый быстрый, L2 находится посередине, а L3 — самый большой и самый медленный из кешей. Над кешами в иерархии находятся небольшие регистры, в которых во время вычислений хранится одно значение данных. Эти регистры по порядку величины являются самыми быстрыми запоминающими устройствами в вашей системе. Когда компилятор преобразует высокоуровневую программу в язык ассемблера, он определит наилучший способ использования этих регистров.

Когда ЦП запрашивает данные из памяти, он сначала проверяет, хранятся ли уже эти данные в кэше L1. Если это так, к данным можно получить быстрый доступ всего за несколько циклов. Если его нет, ЦП проверит L2 и затем выполнит поиск в кэше L3. Кеши реализованы таким образом, что они обычно прозрачны для ядра. Ядро просто запросит некоторые данные по указанному адресу памяти, и любой уровень иерархии, на котором они есть, ответит. Когда мы переходим к следующим этапам иерархии памяти, размер и задержка обычно увеличиваются на порядки.В конце концов, если ЦП не может найти данные, которые он ищет, ни в одном из кешей, только тогда он перейдет в основную память (ОЗУ).

В типичном процессоре каждое ядро ​​имеет два кэша L1: один для данных и один для инструкций. Кэш L1 обычно составляет около 100 килобайт, и размер может варьироваться в зависимости от чипа и поколения. Также обычно имеется кэш L2 для каждого ядра, хотя в некоторых архитектурах он может совместно использоваться двумя ядрами. Кэши L2 обычно составляют несколько сотен килобайт.Наконец, есть единый кэш L3, который используется всеми ядрами и имеет порядок десятков мегабайт.

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

Помимо кэшей, одним из других ключевых строительных блоков современного процессора является точный предсказатель ветвления .Инструкции ветвления аналогичны операторам if для процессора. Один набор инструкций будет выполняться, если условие истинно, а другой будет выполняться, если условие ложно. Например, вы можете сравнить два числа и, если они равны, выполнить одну функцию, а если они разные, выполнить другую функцию. Эти инструкции ветвления чрезвычайно распространены и могут составлять примерно 20% всех инструкций в программе.

На первый взгляд, эти инструкции ветвления могут не показаться проблемой, но на самом деле процессору может быть очень сложно выполнить их правильно.Поскольку в любой момент времени ЦП может быть в процессе выполнения десяти или двадцати инструкций одновременно, очень важно знать , какие инструкции следует выполнить. Может потребоваться 5 циклов, чтобы определить, является ли текущая инструкция ветвью, и еще 10 циклов, чтобы определить, истинно ли условие. За это время процессор мог начать выполнение десятков дополнительных инструкций, даже не зная, были ли эти инструкции правильными для выполнения.

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

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

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

Архитектура, используемая в современных процессорах, прошла долгий путь за последние несколько десятилетий. Инновации и продуманный дизайн привели к повышению производительности и лучшему использованию основного оборудования. Однако производители процессоров очень скрытно относятся к технологиям своих процессоров, поэтому невозможно точно знать, что происходит внутри. При этом основы работы компьютеров стандартизированы для всех процессоров.Intel может добавить свой секретный соус для повышения скорости попадания в кэш, или AMD может добавить расширенный предсказатель ветвления, но они оба выполняют одну и ту же задачу.

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

Эта статья была первоначально опубликована 22 апреля 2019 года. Мы немного изменили ее и изменили в рамках нашей инициативы #ThrowbackThursday.Изображение на шапке: электронная плата крупным планом, Raimudas

.

новейших вопросов по архитектуре процессора — qaru Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
  5. Реклама Обратитесь к разработчикам и технологам со всего мира
.

самых популярных ответов на тему архитектуры процессора — qaruQaruSite Переполнение стека
  1. Около
  2. Товары
  3. Для команд
  1. Переполнение стека Общественные вопросы и ответы
  2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
  3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
  4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
  5. Реклама Обратитесь к разработчикам и технологам со всего мира
  6. О компании

Загрузка…

    .

    новейших вопросов по архитектуре процессора) — qaru Переполнение стека
    1. Около
    2. Товары
    3. Для команд
    1. Переполнение стека Общественные вопросы и ответы
    2. Переполнение стека для команд Где разработчики и технологи делятся частными знаниями с коллегами
    3. Вакансии Программирование и связанные с ним технические возможности карьерного роста
    4. Талант Нанимайте технических специалистов и создавайте свой бренд работодателя
    5. Реклама Обратитесь к разработчикам и технологам со всего мира
    .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *