Архитектура ЭВМ

RISC- и CISC-архитектуры процессоров

Разбить на страницы
Показывать лекцию целиком

CISC- и RISC-архитектура: определение, особенности машинного языка, преимущества и ограничения; пример машинного кода программы на C для процессора Intel x86 (CISC-архитектура) и процессора ARM (RISC-архитектура).

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

ОПРЕДЕЛЕНИЯ, ОСОБЕННОСТИ, ПРЕИМУЩЕСТВА И НЕДОСТАТКИ

Традиционный подход к проектированию процессоров ставил одной из главных задач эффективную аппаратную реализацию часто встречающихся операций и удобство написания программ на языке ассемблера и машинного языка. Этот подход называется CISC-архитектурой (Complicated Instruction Set Computer); данный термин переводится как "компьютер со сложной системой команд".

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

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

  • Выразительность системы команд. Используется большое количество разнообразных команд - от простейших арифметических до сложных, совмещающих, например, арифметические операции и различные проверки операндов (например, на равенство и неравенство или на состояние отдельных битов в них). Системы команд некоторых процессоров поддерживают также работу с массивами данных - копирование, поэлементное сравнение и т.д.
  • Гибкость при задании аргументов команд. Одна операция, например, сложение, может быть представлена в CISC-процессоре целым семейством команд. Все эти команды позволяют различными способами задавать аргументы сложению, которые, таким образом, могут браться из машинного кода, а также из оперативной памяти - или по явно заданному адресу, или по адресу, заданному в регистре. Подобные возможности позволяют минимизировать вспомогательное копирование данных (например, из памяти в регистр) и помогают эффективно кодировать с помощью небольшого числа команд, а часто вообще с помощью одной единственной команды, такие распространённые операции, как, скажем, сравнение двух переменных, или сложение переменной с элементом массива.
  • Экономное кодирование - возможность создавать машинный код, занимающий минимальный объём памяти. Двоичное представление разных команд в оперативной памяти имеет разную длину и разный формат: наиболее частые команды умещаются в один байт, а на редко используемых не экономят, кодируя их пятью или даже более байтами. Это позволяет, в среднем, существенно сократить размер машинного кода.
  • Существенно разная длительность выполнения команд. Простые команды, такие, как обнуление регистра, выполняются в CISC-процессорах быстро, в то время как сложные команды, такие, как деление, требуют значительного времени.
  • В качестве примеров процессоров, имеющих CISC-архитектуру, укажем на процессоры знаменитых менфреймов IBM System/360, а также на процессоры семейства Intel x86.

    Теперь перечислим недостатки CISC-архитектуры.

  • Разработка процессоров с выразительной, но обширной и сложной системой команд является трудозатратной задачей, что повышает стоимость разработки процессоров и риск большого количества ошибок.
  • Выпускаемые процессоры, будучи сложными, имеют высокую себестоимость и рыночную цену.
  • Сложная система команд затрудняет внутрипроцессорные оптимизации, например, автоматическое распараллеливание выполнения машинных команд.
  • Многие CISC-процессоры реализуют сложные команды с помощью микрокода - специализированного машинного языка, позволяющего задавать последовательность действий (микроопераций), выполняемую одной машинной командой процессора. Таким образом команды CISC-процессоров оказываются настолько сложными, что их приходится описывать при помощи дополнительного машинного языка, который исполняется специализированным процессором внутри процессора.

    RISC-архитектура (Reduced Instruction Set Computer) была нацелена на решение этих проблем.

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

    Вот основные свойства процессоров с RISC-архитектурой.

  • Минималистичность системы команд. Машинные команды RISC-процессора имеют простую функциональность, соответственно, время на их декодирование и исполнения оказывается небольшим, а блоки процессора, отвечающие за декодирование - простыми.
  • Отсутствие гибкости в задании аргументов. Обработку и пересылку данных из оперативной памяти в регистры процессора выполняют разные команды, то есть нет арифметических и логических операции, чьи операнды находятся в оперативной памяти и поддерживают различные варианты адресации. Соответственно, арифметические и логические операции реализуются командами, которые работают только с регистрами процессора. Например, нельзя с помощью одной команды сложить два числа, одно из которых находится в регистре, а другое - в памяти, а нужно отдельной командой загрузить значение из памяти в некоторый регистр и только после этого запустить команду сложения. Этот принцип в литературе часто называется load-store architecture, что как раз и означает обмен данными процессора с памятью при помощи отдельных команд. Чтобы компенсировать это ограничение, RISC-процессоры обычно имеют большое количество регистров общего назначения. Большая регистровая память позволяет постоянно держать много данных внутри процессора, и, тем самым, минимизировать количество операций обмена данными с оперативной памятью.
  • Унифицированное кодирование. Двоичное представление разных машинных команд (то есть соответствующий им машинный код) имеет одинаковый формат и фиксированный размер. Для большинства RISC-архитектур одна команда занимает одно машинное слово. Таким образом имеется простой и "единообразный" машинный язык.
  • Фиксированное время выполнения команд. Все команды выполняются за одно и то же количество тактов, что упрощает различные оптимизации, в частности, конвейеризацию, о которой мы подробнее расскажем ниже. Однако в RISC-процессорах имеется некоторое количество сложных команд, время исполнения которых может существенно превышать стандартное, например, умножение и деление. Эти операции сложнее, чем сложение и вычитание: они требуют выполнения большого количества сдвигов, сложений/вычитаний и различных проверок. Поскольку такие команды выбиваются из стройной концепции RISC, для их реализации применяют специальные приёмы. В частности, команда деления исполняется асинхронно - само деление далее выполняется отдельным специальным блоком процессора, в то время как сам процессор исполняет другие команды. При этом исполняемая программа "знает", через сколько тактов деление завершится, и также знает, где (в каких регистрах) будут расположены частное и остаток от деления.
  • Ценой потери выразительности и экономности машинного языка процессоры с RISC-архитектурой достигают следующих преимуществ по сравнению с CISC-процессорами.

  • Упрощение и удешевление процессоров, как при конструировании, так и при производстве.
  • Обширные возможности для реализации различных оптимизаций, в частности, внутрипроцессорного распараллеливания.
  • Чтобы наглядно проиллюстрировать разницу между CISC- RISC- архитектурами, рассмотрим следующий пример. Команда сложения (add) в процессорах семейства Intel x86 (CISC-архитектура) имеет два аргумента - первое и второе слагаемое, а результат исполнения команды помещается на место первого слагаемого. При этом любое из слагаемых может быть или регистром, или числом, хранящимся в оперативной памяти. Все возможные сочетания типов аргументов соответствуют различным командам add. Таким образом, в процессорах Intel x86 имеется три разных команды add: регистр/регистр, регистр/память, память/регистр. Команды add типа память/память у процессоров Intel x86 отсутствует, поскольку в рамках выполнения арифметических команд предполагается не более одного обращения к памяти. Это обусловлено преемственностью в рамках семейства Intel x86: в первых процессорах семейства (Intel 8086 и Intel 8088) несколько обращений к данным в оперативной памяти существенно замедлили бы реализацию арифметики и потребовали бы усложнения процессора. Следует отметить, что кроме вышеперечисленных команд сложения у процессоров Intel x86 имеется и другие команды add, которые предназначены для работы с константами, для использования разных вариантов адресации и пр.

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

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

    RISC-архитектура также имеет свои слабые стороны.

  • Упомянутые выше оптимизации требуют бо?льших, нежели в случае CISC-процессоров, усилий по создании компилятором с языков высокого уровня оптимального машинного кода. Современные CISC-процессоры справляются с этим "самостоятельно", хотя и ценой значительного усложнения. Подробнее об этом мы расскажем ниже в разделе о конвейеризации и внеочередном исполнении машинных команд.
  • Поскольку объем кода для RISC-процессора получается больше, чем для тех же программ, скомпилированных для CISC-архитектур, то увеличивается нагрузка на шины и на оперативную память ЭВМ.
  • Наиболее известными представителями RISC-архитектуры являются семейства ARM (процессоры этого семейства являются основой многих современных мобильных устройств, а также некоторых персональных компьютеров и даже суперкомпьютеров) и MIPS (наиболее популярны как основа для оборудования вычислительных сетей).

    Одним из обстоятельств, повлиявших на популярность RISC-архитектуры (а это был рубеж 1970-х и 80-х годов) стал тот факт, что значительная часть программ к этому времени разрабатывалась на языках высокого уровня, и таким образом с машинным языком уже имели дело компиляторы, а не программисты. Следовательно, необходимость удобного для человека машинного языка (одно из основных преимуществ CISC-архитектуры) стало неактуальным. В то же время RISC-процессоры, хотя и потеснили CISC, но не вытеснили их окончательно. Большинство новых процессоров, разрабатываемых в последние годы, относятся к уже существующим семействам, а большинство этих семейств имеют RISC-архитектуру. Тем не менее, для популярных CISC-семейств процессоров, например, Intel x86 и IBM System/360 (и последующих) разработано такое количество ПО, что отказаться от этих процессоров в пользу других, пусть и более совершенных, уже невозможно по экономическим соображениям. Отметим также, что разработчики современных CISC-процессоров не отказываются от использования отдельных идей RISC. Так, в некоторых процессорах семейства Intel x86 (например, Intel 80486) машинные команды транслируются в последовательности микроопераций, которые уже исполняет "скрытый от программиста" внутренний RISC-процессор.

    ПРИМЕР

    Чтобы наглядно проиллюстрировать особенности CISC- и RISC-архитектур, приведём пример. В качестве CISC-процессора рассмотрим процессор семейства Intel x86, в качестве RISC-процессора возьмём ARM. Рассмотрим следующую несложную программу на C и покажем, какой машинный код создаётся компилятором для этой программы для CISC- и RISC-процессора:

     int a, b; bool res; a = a + b; b = 3 * b; if (a > b) res = true; else res = false; 

    Для компиляции этой программы под платформу Intel x86 мы использовали компилятор Microsoft Visual C/C++ 19, для ARM - компилятор GNU C Compiler 8. Читатели для тех же целей могут воспользоваться сервисом , который позволяет, не инсталлируя эти компиляторы на свой компьютер, транслировать программы на языках C/С++ под разные архитектуры, и наглядно показывает получившийся код на языке ассемблера, а также в виде машинных команд.

    Результаты трансляции для обеих архитектур представлены в рис. 9.1. Для каждого оператора программы на языке C даны команды машинной программы Intel x86 и ARM. Для каждой команды приводится её адрес в оперативной памяти, машинный код (и то, и другое - в шестнадцатеричной записи), а также ассемблерное представление этой команды (для большей наглядности).

    Ниже представлены дополнительные пояснения и комментарии к рис. 9.1.

  • Программа для процессора Intel x86 состоит из 11 команд, а для ARM - из 18.
  • Арифметические регистры в Intel x86 именуются символами, например, eax, ecx, а в ARM они обычно нумеруются, например: r0, r1,\dots Это связано с тем, что традиционно у RISC-процессоров арифметических регистров больше, чем у CISC, поскольку первым предпочтительно как можно больше операндов заранее разместить в регистрах с тем, чтобы во время исполнения основных команд не обращаться к оперативной памяти.
  • Код команд манды процессора Intel x86 имеет разную длину - от одного до четырех байтов вместе с операндами, а код команд ARM занимает в памяти по четыре байта. В итоге программа для Intel x86 занимает 34 байта, а для ARM - 72. Эта закономерность сохраняется и для больших программ: машинный код для процессоров ARM обычно в 1,5-2,5 раза объёмнее, чем для Intel x86.
  • Для Intel x86 компилятор использует умножение (команду imul - умножение целых чисел со знаком), а для ARM умножение заменяется сдвигом и сложением (b * 3 \to b * 2 + b \to b << 1 + b): как уже обсуждалось выше, операция умножения является ресурсоёмкой, поэтому при компиляции программы под RISC-процессор везде, где имеется возможность избежать использования команды машинного умножения, компилятор делает это.
  • Для Intel x86 в командах безусловного (jmp) и условного (jle) перехода параметр, указывающий, насколько следует "прыгнуть" относительно адреса текущей команды (так называемое смещение), задаётся в байтах (например, jmp .+4 означает: "перепрыгни" через четыре байта машинного кода). У ARM все команды, представленные в виде машинного кода, имеют одинаковую длину - по четыре байта. Поэтому команды перехода (b и ble) оперируют не адресом, а сразу номером команды, соответственно и смещение задаётся не в байтах, а в количестве команд, причём не считая следующей (например,jmp .+1 означает: "перепрыгни" через две команды).
  • Отметим также, что мы намеренно запретили использованным компиляторам оптимизировать программу. При включённых оптимизациях современные компиляторы выполняют много преобразований, которые в нашем случае существенно усложнили бы результирующий код, сделав его непригодным для нашей иллюстративной задачи. Читатели могут в качестве упражнения самостоятельно задать параметры оптимизации и посмотреть на то, что получится в итоге.

    Вопросы

  • Дайте определение CISC-архитектуры.
  • Перечислите свойства машинных языков CISC-процессоров.
  • Назовите преимущества и недостатки CISC-архитектуры.
  • Дайте определение RISC-архитектуры.
  • Перечислите свойства машинных языков RISC-процессоров.
  • Назовите преимущества и недостатки RISC-архитектуры.
  • Назовите обстоятельства, повлиявшие на популярность RISC-архитектур.
  • Почему в настоящее время недружественный машинный язык RISC-процессоров не является существенным недостатком?
  • Приведите пример сложной команды, расскажите, как она реализована.
  • Что такое микрокод и для чего он используется?
  • Приведите пример сложной машинной команды CISC-процессора.
  • Перечислите варианты видов аргументов для двухаргументых машинных команд.
  • Продемонстрируйте разницу между CISC- и RISC-процессорами на примере операции сложения.
  • Какие программы имеют больше машинных команд и почему - программы для CISC- или RISC-процессоров?
  • Какие программы имеют больший объем машинного кода - для CISC- или RISC-процессоров?
  • Какие программы выполняются быстрее - для CISC- или RISC-процессоров?
  • Оттранслируйте фрагмент программы на языке C для CISC-процессора, прокомментируйте результаты трансляции.
  • Оттранслируйте фрагмент программы на языке C для RISC-процессора, прокомментируйте результаты трансляции.
  • Литература

  • Гуров В.В. Архитектура микропроцессоров / Интернет-университет информационных технологий, Интернет-Университет Информационных Технологий (ИНТУИТ), Бином. 2010. 272 с.
  • Хорошевский В.Г. Архитектура вычислительных систем.: Учеб. пособие. 2-e изд., перераб. и доп. M.: Изд-во МГТУ им. H.Э. Баумана, 2008. 520 c.
  • Таненбаум Э., Остин Т. Архитектура компьютера. 6-е изд. СПб.: Питер, 2013. 816 с.
  • Patterson D. A., Ditzel D. R. The case for the reduced instruction set computer //ACM SIGARCH Computer Architecture News. 1980, vol. 8, No 6, P. 25-33.
  • Intel 80386 Programmer's Reference Manual. Intel Corporation, 1986.
  • Страницы:

    CISC- и RISC-архитектура: определение, особенности машинного языка, преимущества и ограничения; пример машинного кода программы на C для процессора Intel x86 (CISC-архитектура) и процессора ARM (RISC-архитектура).

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

    ОПРЕДЕЛЕНИЯ, ОСОБЕННОСТИ, ПРЕИМУЩЕСТВА И НЕДОСТАТКИ

    Традиционный подход к проектированию процессоров ставил одной из главных задач эффективную аппаратную реализацию часто встречающихся операций и удобство написания программ на языке ассемблера и машинного языка. Этот подход называется CISC-архитектурой (Complicated Instruction Set Computer); данный термин переводится как "компьютер со сложной системой команд".

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

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

  • Выразительность системы команд. Используется большое количество разнообразных команд - от простейших арифметических до сложных, совмещающих, например, арифметические операции и различные проверки операндов (например, на равенство и неравенство или на состояние отдельных битов в них). Системы команд некоторых процессоров поддерживают также работу с массивами данных - копирование, поэлементное сравнение и т.д.
  • Гибкость при задании аргументов команд. Одна операция, например, сложение, может быть представлена в CISC-процессоре целым семейством команд. Все эти команды позволяют различными способами задавать аргументы сложению, которые, таким образом, могут браться из машинного кода, а также из оперативной памяти - или по явно заданному адресу, или по адресу, заданному в регистре. Подобные возможности позволяют минимизировать вспомогательное копирование данных (например, из памяти в регистр) и помогают эффективно кодировать с помощью небольшого числа команд, а часто вообще с помощью одной единственной команды, такие распространённые операции, как, скажем, сравнение двух переменных, или сложение переменной с элементом массива.
  • Экономное кодирование - возможность создавать машинный код, занимающий минимальный объём памяти. Двоичное представление разных команд в оперативной памяти имеет разную длину и разный формат: наиболее частые команды умещаются в один байт, а на редко используемых не экономят, кодируя их пятью или даже более байтами. Это позволяет, в среднем, существенно сократить размер машинного кода.
  • Существенно разная длительность выполнения команд. Простые команды, такие, как обнуление регистра, выполняются в CISC-процессорах быстро, в то время как сложные команды, такие, как деление, требуют значительного времени.
  • В качестве примеров процессоров, имеющих CISC-архитектуру, укажем на процессоры знаменитых менфреймов IBM System/360, а также на процессоры семейства Intel x86.

    Теперь перечислим недостатки CISC-архитектуры.

  • Разработка процессоров с выразительной, но обширной и сложной системой команд является трудозатратной задачей, что повышает стоимость разработки процессоров и риск большого количества ошибок.
  • Выпускаемые процессоры, будучи сложными, имеют высокую себестоимость и рыночную цену.
  • Сложная система команд затрудняет внутрипроцессорные оптимизации, например, автоматическое распараллеливание выполнения машинных команд.
  • Многие CISC-процессоры реализуют сложные команды с помощью микрокода - специализированного машинного языка, позволяющего задавать последовательность действий (микроопераций), выполняемую одной машинной командой процессора. Таким образом команды CISC-процессоров оказываются настолько сложными, что их приходится описывать при помощи дополнительного машинного языка, который исполняется специализированным процессором внутри процессора.

    RISC-архитектура (Reduced Instruction Set Computer) была нацелена на решение этих проблем.

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

    Вот основные свойства процессоров с RISC-архитектурой.

  • Минималистичность системы команд. Машинные команды RISC-процессора имеют простую функциональность, соответственно, время на их декодирование и исполнения оказывается небольшим, а блоки процессора, отвечающие за декодирование - простыми.
  • Отсутствие гибкости в задании аргументов. Обработку и пересылку данных из оперативной памяти в регистры процессора выполняют разные команды, то есть нет арифметических и логических операции, чьи операнды находятся в оперативной памяти и поддерживают различные варианты адресации. Соответственно, арифметические и логические операции реализуются командами, которые работают только с регистрами процессора. Например, нельзя с помощью одной команды сложить два числа, одно из которых находится в регистре, а другое - в памяти, а нужно отдельной командой загрузить значение из памяти в некоторый регистр и только после этого запустить команду сложения. Этот принцип в литературе часто называется load-store architecture, что как раз и означает обмен данными процессора с памятью при помощи отдельных команд. Чтобы компенсировать это ограничение, RISC-процессоры обычно имеют большое количество регистров общего назначения. Большая регистровая память позволяет постоянно держать много данных внутри процессора, и, тем самым, минимизировать количество операций обмена данными с оперативной памятью.
  • Унифицированное кодирование. Двоичное представление разных машинных команд (то есть соответствующий им машинный код) имеет одинаковый формат и фиксированный размер. Для большинства RISC-архитектур одна команда занимает одно машинное слово. Таким образом имеется простой и "единообразный" машинный язык.
  • Фиксированное время выполнения команд. Все команды выполняются за одно и то же количество тактов, что упрощает различные оптимизации, в частности, конвейеризацию, о которой мы подробнее расскажем ниже. Однако в RISC-процессорах имеется некоторое количество сложных команд, время исполнения которых может существенно превышать стандартное, например, умножение и деление. Эти операции сложнее, чем сложение и вычитание: они требуют выполнения большого количества сдвигов, сложений/вычитаний и различных проверок. Поскольку такие команды выбиваются из стройной концепции RISC, для их реализации применяют специальные приёмы. В частности, команда деления исполняется асинхронно - само деление далее выполняется отдельным специальным блоком процессора, в то время как сам процессор исполняет другие команды. При этом исполняемая программа "знает", через сколько тактов деление завершится, и также знает, где (в каких регистрах) будут расположены частное и остаток от деления.
  • Ценой потери выразительности и экономности машинного языка процессоры с RISC-архитектурой достигают следующих преимуществ по сравнению с CISC-процессорами.

  • Упрощение и удешевление процессоров, как при конструировании, так и при производстве.
  • Обширные возможности для реализации различных оптимизаций, в частности, внутрипроцессорного распараллеливания.
  • Чтобы наглядно проиллюстрировать разницу между CISC- RISC- архитектурами, рассмотрим следующий пример. Команда сложения (add) в процессорах семейства Intel x86 (CISC-архитектура) имеет два аргумента - первое и второе слагаемое, а результат исполнения команды помещается на место первого слагаемого. При этом любое из слагаемых может быть или регистром, или числом, хранящимся в оперативной памяти. Все возможные сочетания типов аргументов соответствуют различным командам add. Таким образом, в процессорах Intel x86 имеется три разных команды add: регистр/регистр, регистр/память, память/регистр. Команды add типа память/память у процессоров Intel x86 отсутствует, поскольку в рамках выполнения арифметических команд предполагается не более одного обращения к памяти. Это обусловлено преемственностью в рамках семейства Intel x86: в первых процессорах семейства (Intel 8086 и Intel 8088) несколько обращений к данным в оперативной памяти существенно замедлили бы реализацию арифметики и потребовали бы усложнения процессора. Следует отметить, что кроме вышеперечисленных команд сложения у процессоров Intel x86 имеется и другие команды add, которые предназначены для работы с константами, для использования разных вариантов адресации и пр.

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

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

    RISC-архитектура также имеет свои слабые стороны.

  • Упомянутые выше оптимизации требуют бо?льших, нежели в случае CISC-процессоров, усилий по создании компилятором с языков высокого уровня оптимального машинного кода. Современные CISC-процессоры справляются с этим "самостоятельно", хотя и ценой значительного усложнения. Подробнее об этом мы расскажем ниже в разделе о конвейеризации и внеочередном исполнении машинных команд.
  • Поскольку объем кода для RISC-процессора получается больше, чем для тех же программ, скомпилированных для CISC-архитектур, то увеличивается нагрузка на шины и на оперативную память ЭВМ.
  • Наиболее известными представителями RISC-архитектуры являются семейства ARM (процессоры этого семейства являются основой многих современных мобильных устройств, а также некоторых персональных компьютеров и даже суперкомпьютеров) и MIPS (наиболее популярны как основа для оборудования вычислительных сетей).

    Одним из обстоятельств, повлиявших на популярность RISC-архитектуры (а это был рубеж 1970-х и 80-х годов) стал тот факт, что значительная часть программ к этому времени разрабатывалась на языках высокого уровня, и таким образом с машинным языком уже имели дело компиляторы, а не программисты. Следовательно, необходимость удобного для человека машинного языка (одно из основных преимуществ CISC-архитектуры) стало неактуальным. В то же время RISC-процессоры, хотя и потеснили CISC, но не вытеснили их окончательно. Большинство новых процессоров, разрабатываемых в последние годы, относятся к уже существующим семействам, а большинство этих семейств имеют RISC-архитектуру. Тем не менее, для популярных CISC-семейств процессоров, например, Intel x86 и IBM System/360 (и последующих) разработано такое количество ПО, что отказаться от этих процессоров в пользу других, пусть и более совершенных, уже невозможно по экономическим соображениям. Отметим также, что разработчики современных CISC-процессоров не отказываются от использования отдельных идей RISC. Так, в некоторых процессорах семейства Intel x86 (например, Intel 80486) машинные команды транслируются в последовательности микроопераций, которые уже исполняет "скрытый от программиста" внутренний RISC-процессор.

    ПРИМЕР

    Чтобы наглядно проиллюстрировать особенности CISC- и RISC-архитектур, приведём пример. В качестве CISC-процессора рассмотрим процессор семейства Intel x86, в качестве RISC-процессора возьмём ARM. Рассмотрим следующую несложную программу на C и покажем, какой машинный код создаётся компилятором для этой программы для CISC- и RISC-процессора:

     int a, b; bool res; a = a + b; b = 3 * b; if (a > b) res = true; else res = false; 

    Для компиляции этой программы под платформу Intel x86 мы использовали компилятор Microsoft Visual C/C++ 19, для ARM - компилятор GNU C Compiler 8. Читатели для тех же целей могут воспользоваться сервисом , который позволяет, не инсталлируя эти компиляторы на свой компьютер, транслировать программы на языках C/С++ под разные архитектуры, и наглядно показывает получившийся код на языке ассемблера, а также в виде машинных команд.

    Результаты трансляции для обеих архитектур представлены в рис. 9.1. Для каждого оператора программы на языке C даны команды машинной программы Intel x86 и ARM. Для каждой команды приводится её адрес в оперативной памяти, машинный код (и то, и другое - в шестнадцатеричной записи), а также ассемблерное представление этой команды (для большей наглядности).

    Ниже представлены дополнительные пояснения и комментарии к рис. 9.1.

  • Программа для процессора Intel x86 состоит из 11 команд, а для ARM - из 18.
  • Арифметические регистры в Intel x86 именуются символами, например, eax, ecx, а в ARM они обычно нумеруются, например: r0, r1,\dots Это связано с тем, что традиционно у RISC-процессоров арифметических регистров больше, чем у CISC, поскольку первым предпочтительно как можно больше операндов заранее разместить в регистрах с тем, чтобы во время исполнения основных команд не обращаться к оперативной памяти.
  • Код команд манды процессора Intel x86 имеет разную длину - от одного до четырех байтов вместе с операндами, а код команд ARM занимает в памяти по четыре байта. В итоге программа для Intel x86 занимает 34 байта, а для ARM - 72. Эта закономерность сохраняется и для больших программ: машинный код для процессоров ARM обычно в 1,5-2,5 раза объёмнее, чем для Intel x86.
  • Для Intel x86 компилятор использует умножение (команду imul - умножение целых чисел со знаком), а для ARM умножение заменяется сдвигом и сложением (b * 3 \to b * 2 + b \to b << 1 + b): как уже обсуждалось выше, операция умножения является ресурсоёмкой, поэтому при компиляции программы под RISC-процессор везде, где имеется возможность избежать использования команды машинного умножения, компилятор делает это.
  • Для Intel x86 в командах безусловного (jmp) и условного (jle) перехода параметр, указывающий, насколько следует "прыгнуть" относительно адреса текущей команды (так называемое смещение), задаётся в байтах (например, jmp .+4 означает: "перепрыгни" через четыре байта машинного кода). У ARM все команды, представленные в виде машинного кода, имеют одинаковую длину - по четыре байта. Поэтому команды перехода (b и ble) оперируют не адресом, а сразу номером команды, соответственно и смещение задаётся не в байтах, а в количестве команд, причём не считая следующей (например,jmp .+1 означает: "перепрыгни" через две команды).
  • Отметим также, что мы намеренно запретили использованным компиляторам оптимизировать программу. При включённых оптимизациях современные компиляторы выполняют много преобразований, которые в нашем случае существенно усложнили бы результирующий код, сделав его непригодным для нашей иллюстративной задачи. Читатели могут в качестве упражнения самостоятельно задать параметры оптимизации и посмотреть на то, что получится в итоге.

    Вопросы

  • Дайте определение CISC-архитектуры.
  • Перечислите свойства машинных языков CISC-процессоров.
  • Назовите преимущества и недостатки CISC-архитектуры.
  • Дайте определение RISC-архитектуры.
  • Перечислите свойства машинных языков RISC-процессоров.
  • Назовите преимущества и недостатки RISC-архитектуры.
  • Назовите обстоятельства, повлиявшие на популярность RISC-архитектур.
  • Почему в настоящее время недружественный машинный язык RISC-процессоров не является существенным недостатком?
  • Приведите пример сложной команды, расскажите, как она реализована.
  • Что такое микрокод и для чего он используется?
  • Приведите пример сложной машинной команды CISC-процессора.
  • Перечислите варианты видов аргументов для двухаргументых машинных команд.
  • Продемонстрируйте разницу между CISC- и RISC-процессорами на примере операции сложения.
  • Какие программы имеют больше машинных команд и почему - программы для CISC- или RISC-процессоров?
  • Какие программы имеют больший объем машинного кода - для CISC- или RISC-процессоров?
  • Какие программы выполняются быстрее - для CISC- или RISC-процессоров?
  • Оттранслируйте фрагмент программы на языке C для CISC-процессора, прокомментируйте результаты трансляции.
  • Оттранслируйте фрагмент программы на языке C для RISC-процессора, прокомментируйте результаты трансляции.
  • Литература

  • Гуров В.В. Архитектура микропроцессоров / Интернет-университет информационных технологий, Интернет-Университет Информационных Технологий (ИНТУИТ), Бином. 2010. 272 с.
  • Хорошевский В.Г. Архитектура вычислительных систем.: Учеб. пособие. 2-e изд., перераб. и доп. M.: Изд-во МГТУ им. H.Э. Баумана, 2008. 520 c.
  • Таненбаум Э., Остин Т. Архитектура компьютера. 6-е изд. СПб.: Питер, 2013. 816 с.
  • Patterson D. A., Ditzel D. R. The case for the reduced instruction set computer //ACM SIGARCH Computer Architecture News. 1980, vol. 8, No 6, P. 25-33.
  • Intel 80386 Programmer's Reference Manual. Intel Corporation, 1986.
  • Вернуться к учебному плану