A компьютер со сложным набором команд (CISC ) - это компьютер, на котором отдельные инструкции могут выполнять несколько низкоуровневых операций (например, загрузка из памяти, арифметические операции и хранилище памяти ) или могут выполнять многоступенчатые операции или режимы адресации в рамках отдельных инструкций. Этот термин был придуман задним числом в отличие от компьютера с сокращенным набором команд (RISC) и поэтому стал чем-то вроде зонтичного термина для всего, что не является RISC, от большого и сложного от мэйнфреймов до упрощенных микроконтроллеров, где операции загрузки и сохранения памяти не отделены от арифметических инструкций. Единственная типичная отличительная особенность состоит в том, что в большинстве проектов RISC используется одинаковая длина инструкции почти для всех инструкций и используются строго отдельные инструкции загрузки и сохранения.
Примеры архитектур с набором команд, которые были задним числом помечены как CISC: System / 360 - z / Architecture, PDP-11 и VAX архитектуры, Data General Nova и многие другие. Хорошо известные микропроцессоры и микроконтроллеры, которые также были помечены как CISC во многих научных публикациях, включают семейства Motorola 6800, 6809 и 68000 ; семейства Intel 8080, iAPX432 и x86 ; семейства Zilog Z80, Z8 и Z8000 ; линии National Semiconductor 32016 и NS320xx ; семейство MOS Technology 6502 ; семейство Intel 8051 ; и другие.
Некоторые авторы считают некоторые образцы пограничными. Например, Microchip Technology PIC была помечена в одних кругах как RISC, а в других - CISC. Оба 6502 и 6809 были описаны как RISC-подобные, хотя они имеют сложные режимы адресации, а также арифметические инструкции, которые работают с памятью, вопреки принципам RISC.
До того, как философия RISC стала заметной, многие компьютерные архитекторы пытались восполнить так называемый семантический пробел, т. Е. Разработать наборы инструкций, которые напрямую поддерживают конструкции программирования высокого уровня, такие как вызовы процедур, управление циклом и сложные режимы адресации, позволяющие объединить доступ к структуре данных и массиву в отдельные инструкции. Инструкции также обычно сильно кодируются, чтобы еще больше повысить плотность кода. Компактный характер таких наборов инструкций приводит к меньшему размеру программы и меньшему (медленному) доступу к основной памяти, что в то время (начало 1960-х годов и далее) приводило к огромной экономии на стоимости компьютерной памяти и диска. хранилище, а также более быстрое выполнение. Это также означало хорошую продуктивность программирования даже на языке ассемблера, так как языки высокого уровня, такие как Fortran или Algol не всегда были доступны или уместны. Действительно, микропроцессоры этой категории иногда все еще программируются на языке ассемблера для определенных типов критических приложений.
В 1970-х годах анализ языков высокого уровня указал на некоторые сложные реализации машинного языка, и было определено, что новые инструкции могут улучшить производительность. Были добавлены некоторые инструкции, которые никогда не предназначались для использования на языке ассемблера, но хорошо подходят для скомпилированных языков высокого уровня. Компиляторы были обновлены, чтобы воспользоваться этими инструкциями. Преимущества семантически богатых инструкций с компактным кодированием можно увидеть и в современных процессорах, особенно в высокопроизводительном сегменте, где кеши являются центральным компонентом (в отличие от большинства встроенных систем ). Это связано с тем, что эти быстрые, но сложные и дорогие блоки памяти по своей природе ограничены по размеру, что делает компактный код полезным. Конечно, основная причина их необходимости заключается в том, что основная память (то есть динамическая RAM сегодня) остается медленной по сравнению с (высокопроизводительным) ядром ЦП.
Хотя многие проекты достигли цели повышения пропускной способности при более низких затратах, а также позволяли выражать конструкции языка высокого уровня меньшим количеством инструкций, было замечено, что это не всегда было кейс. Например, младшие версии сложных архитектур (то есть с использованием меньшего количества оборудования) могут привести к ситуациям, когда можно было улучшить производительность, не используя сложную инструкцию (например, вызов процедуры или инструкцию ввода), а вместо этого используя последовательность более простые инструкции.
Одной из причин этого было то, что архитекторы (авторы микрокода ) иногда «переоценивали» инструкции на языке ассемблера, включая функции, которые не могли быть эффективно реализованы на доступном базовом оборудовании. Например, могут быть «побочные эффекты» (выше обычных флагов), такие как установка регистра или ячейки памяти, которые, возможно, использовались редко; если бы это было сделано через обычные (не дублированные) внутренние шины или даже внешнюю шину, это потребовало бы дополнительных циклов каждый раз и, следовательно, было бы довольно неэффективным.
Даже в сбалансированных высокопроизводительных схемах высококодированные и (относительно) высокоуровневые инструкции могут быть сложными для декодирования и эффективного выполнения в пределах ограниченного бюджета транзисторов. Таким образом, такие архитектуры требовали большой работы со стороны разработчика процессора в случаях, когда более простое, но (обычно) более медленное решение, основанное на таблицах декодирования и / или последовательности микрокода, не подходит. В то время, когда транзисторы и другие компоненты были ограниченным ресурсом, это также оставляло меньше компонентов и меньше возможностей для других типов оптимизации производительности.
Схема, которая выполняет действия, определенные микрокодом во многих (но не во всех) процессорах CISC, сама по себе является процессором, который во многих отношениях по своей структуре напоминает очень ранние разработки ЦП. В начале 1970-х это дало толчок идеям вернуться к более простым конструкциям процессоров, чтобы облегчить работу без (тогда относительно больших и дорогих) таблиц ПЗУ и / или структур PLA для секвенирования и / или или расшифровка. Первый (задним числом) RISC-маркированный процессор (IBM 801 - IBM, Watson Research Center, середина 1970-х) был жестко конвейерной простой машиной, первоначально предназначенной для использования в качестве внутреннего ядро микрокода или движок в проектах CISC, но также стал процессором, который представил идею RISC несколько более широкой публике. Простота и регулярность также в видимом наборе инструкций упростила бы реализацию перекрывающихся этапов процессора (конвейерная обработка ) на уровне машинного кода (то есть на уровне, видимом компиляторами). Однако конвейерная обработка на этом уровне уже использовалась в некоторых высокопроизводительных «суперкомпьютерах» CISC для сокращения времени цикла команд (несмотря на сложности реализации в рамках ограниченного количества компонентов и сложности соединения, возможной в то время). С другой стороны, выполнение внутреннего микрокода в процессорах CISC может быть более или менее конвейерным в зависимости от конкретной конструкции и, следовательно, более или менее похоже на базовую структуру процессоров RISC.
В более современном контексте сложное кодирование переменной длины, используемое некоторыми типичными архитектурами CISC, делает сложным, но все же выполнимым создание суперскаляра реализация модели программирования CISC напрямую; Стандартный суперскаляр Pentium в упорядоченном порядке и суперскалярный Cyrix 6x86 - хорошо известные примеры этого. Частые обращения к памяти для операндов типичной машины CISC могут ограничивать параллелизм на уровне инструкций, который может быть извлечен из кода, хотя это в значительной степени опосредовано быстрыми структурами кеша, используемыми в современных проектах, а также другими мерами. Из-за по своей сути компактных и семантически богатых инструкций, средний объем работы, выполняемой на единицу машинного кода (то есть на один байт или бит), выше для CISC, чем для процессора RISC, что может дать ему значительное преимущество в современной реализации на основе кеша.
Транзисторы для логики, PLA и микрокода больше не являются дефицитным ресурсом; только большая высокоскоростная кэш-память ограничена максимальным количеством транзисторов сегодня. Несмотря на сложность, количество транзисторов в декодерах CISC не растет экспоненциально, как общее количество транзисторов на процессор (большинство из которых обычно используется для кэшей). Вместе с лучшими инструментами и усовершенствованными технологиями это привело к новым реализациям проектов с высокой степенью кодирования и переменной длины без ограничений загрузки-сохранения (т.е. без RISC). Это регулирует повторные реализации старых архитектур, таких как повсеместная x86 (см. Ниже), а также новые разработки для микроконтроллеров для встроенных систем и аналогичные применения. Суперскалярная сложность в случае современной x86 была решена путем преобразования инструкций в одну или несколько микроопераций и динамического выполнения этих микроопераций, то есть косвенного и динамического суперскалярного выполнения; Pentium Pro и AMD K5 - ранние примеры этого. Это позволяет разместить довольно простой суперскалярный дизайн после (довольно сложных) декодеров (и буферов), давая, так сказать, лучшее из обоих миров во многих отношениях. Этот метод также используется в микропроцессорах IBM z196 и более поздних версиях z / Architecture.
Термины CISC и RISC стали менее значимыми в связи с продолжающимся развитием проектов и реализаций как CISC, так и RISC. Первые реализации x86 с высокой (или жесткой) конвейеризацией, 486 разработок от Intel, AMD, Cyrix и IBM, поддерживали все инструкций, которые выполняли их предшественники, но достигли максимальной эффективности только на довольно простом подмножестве x86, которое было лишь немного больше, чем типичный набор инструкций RISC (то есть без типичных ограничений RISC load-store ). Поколение Intel P5 Pentium было суперскалярной версией этих принципов. Однако современные процессоры x86 также (обычно) декодируют и разделяют инструкции на динамические последовательности с внутренней буферизацией микроопераций, что не только помогает выполнять большее подмножество инструкций конвейерным (перекрывающимся) способом, но и упрощает более продвинутое извлечение параллелизма из кодового потока для еще более высокой производительности.
Вопреки популярным упрощениям (присутствующим также в некоторых академических текстах), не все CISC закодированы или содержат «сложные» инструкции. Поскольку CISC стал универсальным термином, означающим все, что не является архитектурой загрузочного хранилища (RISC), CISC определяют не количество инструкций, не сложность реализации или сами инструкции, а тот факт, что арифметические инструкции также выполнять доступ к памяти. По сравнению с небольшим 8-битным процессором CISC, инструкция с плавающей запятой RISC сложна. CISC даже не нужно иметь сложные режимы адресации; 32- или 64-разрядные процессоры RISC могут иметь более сложные режимы адресации, чем небольшие 8-разрядные процессоры CISC.
A PDP-10, PDP-8, Intel 80386, Intel 4004, Motorola 68000, мэйнфрейм System z, Burroughs B5000, VAX, Zilog Z80000 и MOS Technology 6502 все сильно различаются по количеству, размерам и форматам инструкций, количеству, типам и размерам регистров и доступным типам данных. Некоторые из них имеют аппаратную поддержку таких операций, как сканирование подстроки, арифметика BCD произвольной точности или трансцендентные функции, в то время как другие имеют только 8-битное сложение и вычитание. Но все они относятся к категории CISC, потому что у них есть инструкции «загрузка-работа», которые загружают и / или сохраняют содержимое памяти в рамках тех же инструкций, которые выполняют фактические вычисления. Например, PDP-8, имеющий всего 8 инструкций фиксированной длины и вообще не имеющий микрокода, является CISC из-за того, как работают инструкции, PowerPC, который имеет более 230 инструкций (больше, чем некоторые VAX), и сложными внутренними компонентами, такими как регистр переименование и буфер переупорядочения - это RISC, тогда как Minimal CISC имеет 8 инструкций, но явно является CISC, поскольку он объединяет доступ к памяти и вычисления в одних и тех же инструкциях.