Введение

IBM CPU 1970-х годов. Экспериментальный миникомпьютер IBM. 801 был экспериментальным центральным процессором (CPU), разработанным IBM в 1970-х годах. Он считается первым современным дизайном RISC, полагающимся на регистры процессора для всех вычислений и устраняющим множество различных режимов адресации, характерных для конструкций CISC. Первоначально разработанный как процессор для телефонной станции, он впоследствии был использован в качестве основы для миникомпьютера и ряда продуктов для линейки мейнфреймов IBM. Изначальная разработка представляла собой 24-битный процессор, который вскоре был заменен 32-битными реализациями тех же концепций, а оригинальный 24-битный 801 использовался лишь до начала 1980-х годов. 801 оказал огромное влияние на компьютерный рынок. Обладая большим объемом данных о производительности, IBM смогла продемонстрировать, что простая конструкция способна легко превзойти даже самые мощные классические конструкции процессоров, при этом генерируя машинный код, лишь незначительно превышающий по размеру сильно оптимизированные инструкции CISC. Применение этих же методов даже к существующим процессорам, таким как System/370, обычно удваивало производительность этих систем. Это продемонстрировало ценность концепции RISC, и все последующие системы IBM были основаны на принципах, разработанных в рамках проекта 801. За свою работу над 801 Джон Кок был удостоен ряда наград и медалей, включая Премию Тьюринга в 1987 году, Национальную медаль в области технологий в 1991 году и Национальную медаль в области науки в 1994 году.

Первоначальная концепция

В 1974 году IBM начала изучать возможность создания телефонного коммутатора, способного обрабатывать миллион звонков в час, или около 300 звонков в секунду. Они подсчитали, что для завершения каждого звонка потребуется 20 000 инструкций, и с учетом накладных расходов на синхронизацию и других факторов, такая машина требовала бы производительности около 12 MIPS. Это потребовало бы значительного повышения производительности; их текущая флагманская модель, IBM System/370 Model 168 конца 1972 года, обеспечивала около 3 MIPS. Группа, работавшая над этим проектом в Исследовательском центре имени Томаса Дж. Уотсона, включая Джона Кока, разработала процессор для этой цели. Чтобы достичь необходимой производительности, они проанализировали, какие операции требуются такой машине, и удалили все неподходящие. Это привело, например, к исключению блока операций с плавающей точкой, который не был бы нужен в этом приложении. Более существенно, они также удалили многие инструкции, работающие с данными в основной памяти, оставив только те, которые работали с внутренними регистрами процессора, поскольку они были намного быстрее, и простой код телефонного коммутатора можно было написать, используя только эти типы инструкций. Результатом этой работы стал концептуальный проект упрощенного процессора с требуемой производительностью. Проект телефонного коммутатора был отменен в 1975 году, но команда добилась значительного прогресса в разработке концепции, и в октябре IBM решила продолжить ее как проект общего назначения. Поскольку не было очевидного проекта, к которому можно было бы ее привязать, команда решила назвать ее "801" в честь здания, в котором они работали. Для задач общего назначения команда начала рассматривать реальные программы, которые могли бы выполняться на типичном мини-компьютере. IBM собрала огромный объем статистических данных о производительности реальных рабочих нагрузок на своих машинах, и эти данные показали, что более половины времени в типичной программе тратится на выполнение всего пяти инструкций: загрузка значения из памяти, сохранение значения в память, переход, сравнение чисел с фиксированной точкой и сложение чисел с фиксированной точкой. Это позволило предположить, что тот же упрощенный дизайн процессора будет работать так же хорошо для мини-компьютера общего назначения, как и для специализированного коммутатора.

Обоснование против использования микрокода

Этот вывод противоречил современным подходам к проектированию процессоров, основанным на использовании микрокода. IBM была одной из первых компаний, широко применивших эту технику в своей серии System/360. Системы 360 и 370 выпускались в различных вариантах производительности, но все они работали с одним и тем же машинным кодом. В высокопроизводительных моделях многие инструкции выполнялись непосредственно аппаратными средствами, например, блоком операций с плавающей точкой, в то время как в малопроизводительных моделях эти же инструкции могли эмулироваться с помощью последовательности других инструкций, закодированных в микрокоде. Это позволяло использовать единый двоичный интерфейс приложений для всей линейки продуктов и давало клиентам уверенность в том, что при необходимости они смогут перейти на более производительную машину без каких-либо других изменений. Микрокод позволял простому процессору поддерживать множество инструкций, что было использовано разработчиками для реализации широкого спектра режимов адресации. Например, инструкция ADD могла иметь дюжину вариантов: одна для сложения двух чисел во внутренних регистрах, другая для сложения регистра и значения из памяти, третья для сложения двух значений из памяти и так далее. Это позволяло программисту выбирать наиболее подходящий вариант для конкретной задачи. Процессор считывал инструкцию и использовал микрокод для ее разложения на последовательность внутренних инструкций. Например, сложение двух чисел из памяти могло быть реализовано путем загрузки этих чисел в регистры, их сложения и последующей записи суммы обратно в память. Стремление предоставить все возможные режимы адресации для всех инструкций стало целью разработчиков процессоров, и эта концепция получила название ортогонального набора инструкций. Команда 801 заметила побочный эффект этой концепции: при наличии множества возможных вариантов инструкции авторы компиляторов почти всегда выбирали один конкретный вариант. Как правило, это был тот вариант, который был реализован аппаратно в малопроизводительных машинах. Это гарантировало, что машинный код, генерируемый компилятором, будет выполняться максимально быстро на всей линейке продуктов. Хотя использование других вариантов инструкций могло быть еще быстрее на машинах, где они были реализованы аппаратно, сложность выбора оптимального варианта из постоянно меняющегося списка машин делала это крайне непрактичным, и авторы компиляторов в основном игнорировали эти возможности. В результате большинство инструкций, доступных в наборе инструкций, никогда не использовались в скомпилированных программах. И именно здесь команда 801 сделала ключевой вывод проекта:

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

Первые реализации

Первоначально предлагаемая архитектура представляла собой машину с шестнадцатью 24-битными регистрами и без виртуальной памяти. В инструкциях использовался формат с двумя операндами, поэтому инструкции обычно имели вид A = A + B, в отличие от формата с тремя операндами, A = B + C. Полученный процессор был работоспособен к лету 1980 года и был реализован с использованием дискретной компонентной технологии Motorola MECL 10K на больших платах с проводной обмоткой. Процессор работал на тактовой частоте 66 нс (приблизительно 15,15 МГц) и мог выполнять вычисления со скоростью около 15 МИПС. Архитектура 801 использовалась в различных устройствах IBM, включая контроллеры каналов для их мейнфреймов S/370 (таких как IBM 3090), различные сетевые устройства, а также в качестве блока вертикального исполнения микрокода в процессорах 9373 и 9375 семейства мейнфреймов IBM 9370. Оригинальная версия архитектуры 801 послужила основой для архитектуры микропроцессора IBM ROMP.

Позднейшие изменения

Первоначально разработанная для системы с ограниченной функциональностью, архитектура 801 не обладала рядом функций, характерных для более крупных машин. Особенно выделялось отсутствие аппаратной поддержки виртуальной памяти, которая не требовалась для роли контроллера и была реализована программно в ранних системах 801, которым она была необходима. Для более широкого применения аппаратная поддержка была обязательным условием. Кроме того, к 1980-м годам компьютерная индустрия в целом переходила к 32-битным системам, и существовало стремление сделать то же самое и с 801. Переход к 32-битному формату имел еще одно существенное преимущество. На практике оказалось, что формат с двумя операндами неудобен в использовании в стандартном математическом коде. В идеале оба входных операнда должны оставаться в регистрах, где их можно повторно использовать в последующих операциях. В формате с двумя операндами одно из двух значений перезаписывалось результатом, и часто приходилось повторно загружать одно из значений из памяти. Переход к 32-битному формату позволил добавить дополнительный регистр в машинные слова, чтобы вывод таких операций можно было направлять в отдельный регистр. Увеличенное машинное слово также позволило увеличить количество регистров с шестнадцати до тридцати двух, что стало очевидным при анализе кода 801. Несмотря на расширение машинных слов с 24 до 32 бит, программы не увеличились на соответствующие 33% за счет сокращения операций загрузки и сохранения, ставших возможными благодаря этим двум изменениям. К другим желательным дополнениям относились инструкции для работы со строковыми данными, закодированными в "упакованном" формате с несколькими символами ASCII в одном машинном слове, а также функции для работы с двоично-десятичным кодом, включая сумматор, способный выполнять перенос для четырехбитных десятичных чисел. Когда новая версия 801 была запущена в качестве эмулятора на 370, команда была удивлена, обнаружив, что код, скомпилированный для 801 и запущенный в эмуляторе, часто работал быстрее, чем тот же исходный код, скомпилированный непосредственно в машинный код 370 с использованием компилятора PL/I 370. Когда они перенесли свой экспериментальный язык "PL.8" на 370 и скомпилировали приложения с его помощью, скорость выполнения увеличилась в три раза по сравнению с версией PL/1. Это было связано с тем, что компилятор принимал решения, подобные тем, что используются в RISC-архитектурах, относительно компиляции кода во внутренние регистры, тем самым оптимизируя доступ к памяти. Эти операции были столь же затратными на 370, как и на 801, но эта стоимость обычно скрывалась простотой одной строки кода CISC. Компилятор PL.8 был гораздо более агрессивным в плане избежания операций загрузки и сохранения, что приводило к повышению производительности даже на процессоре CISC.

Проекты "Гипард", "Пантера" и "Америка"

В начале 1980-х годов опыт, полученный при работе над 801, был объединен с результатами проекта IBM Advanced Computer Systems, что привело к созданию экспериментального процессора под названием "Cheetah" (Гепард). Cheetah был двухпоточным суперскалярным процессором, который в 1985 году эволюционировал в процессор "Panther" (Пантера), а в 1986 году – в четырехпоточный суперскалярный дизайн "America" (Америка). Это был набор из трех чипов, включающий процессор команд, осуществляющий выборку и декодирование инструкций, процессор с фиксированной точкой, разделяющий задачи с процессором команд, и процессор с плавающей точкой для систем, которым он необходим. Разработанный командой 801, окончательный проект был отправлен в офис IBM в Остине в 1986 году, где на его основе была разработана система IBM RS/6000. RS/6000 с частотой 25 МГц был одним из самых быстрых компьютеров своего времени. В стандартных тестах он превосходил другие RISC-машины в два-три раза и значительно опережал более старые системы CISC. После RS/6000 компания сосредоточилась на версии концепций 801, которую можно было бы эффективно производить в различных масштабах. Результатом стали архитектура набора команд IBM POWER и ответвление PowerPC.