Введение
Тип набора команд
В компьютерной инженерии ортогональный набор команд — это архитектура набора команд, в которой все типы команд могут использовать все режимы адресации. Он "ортогонален" в том смысле, что тип команды и режим адресации варьируются независимо друг от друга. Ортогональный набор команд не накладывает ограничений, требующих от определенной команды использования конкретного регистра, что минимизирует перекрытие функциональности команд. Ортогональность считалась важной целью для разработчиков процессоров в 1970-х годах, и VAX 11 часто используется в качестве эталона для этой концепции. Однако внедрение принципов проектирования RISC в 1980-х годах значительно изменило тенденцию в сторону большей ортогональности. Современные процессоры часто имитируют ортогональность на этапе предварительной обработки перед выполнением фактических задач в ядре, подобном RISC. Эта "симулированная ортогональность" в целом является более широким понятием, включающим принципы разделения и полноты в библиотеках функций, как в математической концепции: ортогональный набор функций легко использовать в качестве основы для разложения сложных функций, обеспечивая отсутствие влияния изменений одной части на другие.
In computer engineering, an orthogonal instruction set is an instruction set architecture where all instruction types can use all addressing modes. It is "orthogonal" in the sense that the instruction type and the addressing mode vary independently. An orthogonal instruction set does not impose a limitation that requires a certain instruction to use a specific register so there is little overlapping of instruction functionality. Orthogonality was considered a major goal for processor designers in the 1970s, and the VAX 11 is often used as the benchmark for this concept. However, the introduction of RISC design philosophies in the 1980s significantly reversed the trend against more orthogonality. Modern CPUs often simulate orthogonality in a preprocessing step before performing the actual tasks in a RISC like core. This "simulated orthogonality" in general is a broader concept, encompassing the notions of decoupling and completeness in function libraries, like in the mathematical concept: an orthogonal function set is easy to use as a basis into expanded functions, ensuring that parts don’t affect another if we change one part.
Основные понятия
В основе всех компьютеров общего назначения лежит единый принцип работы: данные, хранящиеся в основной памяти, считываются центральным процессором (ЦПУ) во временную, более быструю память (например, регистры ЦПУ), над ними выполняются операции, а затем они записываются обратно в основную память. Память состоит из набора значений данных, закодированных в числовом виде и адресуемых по своим адресам, которые также являются числовыми значениями. Это означает, что к адресам можно применять те же операции, что и к самим данным. Во время обработки данные могут временно храниться в регистрах процессора – это быстрые ячейки памяти для промежуточных вычислений. Регистры используются, например, для суммирования последовательности чисел.
8080 и последующие модели
8-битный микропроцессор Intel 8080 (а также 8085 и 8051) представлял собой, по сути, слегка расширенную конструкцию на основе аккумулятора и, следовательно, не был ортогональным. Программист на языке ассемблера или разработчик компилятора должны были учитывать, какие операции возможны для каждого регистра: большинство 8-битных операций можно было выполнять только с 8-битным аккумулятором (регистр A), в то время как 16-битные операции – только с 16-битным указателем/аккумулятором (парой регистров HL), тогда как простые операции, такие как инкремент, были возможны со всеми семью 8-битными регистрами. Это во многом объяснялось стремлением сохранить все опкоды длиной в один байт. Бинарно совместимый Z80 позже добавил префиксные коды, чтобы обойти это ограничение в один байт и обеспечить более мощный набор инструкций. Та же основная идея была использована в Intel 8086, однако, чтобы обеспечить более существенные расширения, бинарная совместимость с 8080 здесь не поддерживалась. Он сохранил некоторую степень неортогональности ради высокой плотности кода в то время. 32-битное расширение этой архитектуры, представленное с 80386, стало несколько более ортогональным, несмотря на сохранение всех инструкций 8086 и их расширенных версий. Однако используемая стратегия кодирования по-прежнему несет множество следов от 8008 и 8080 (и Z80). Например, однобайтовые кодировки остаются для определенных часто используемых операций, таких как push и pop регистров и констант; а основной аккумулятор, регистр EAX, использует более короткие кодировки, чем другие регистры, для определенных типов операций. Подобные наблюдения иногда используются для оптимизации кода как в компиляторах, так и в коде, написанном вручную.
RISC
Ряд исследований, проведённых в 1970-х годах, показал, что гибкость, предоставляемая ортогональными режимами, редко или вовсе не использовалась при решении реальных задач. В частности, в IBM был изучен трассировочный вывод кода, выполнявшегося на System/370, и было продемонстрировано, что в реальных программах использовалась лишь малая часть доступных режимов. Аналогичные исследования, часто посвящённые VAX, выявили ту же закономерность. В некоторых случаях было показано, что сложность инструкций приводила к увеличению времени их выполнения по сравнению с последовательностью более простых инструкций, каноническим примером чего является инструкция INDEX в VAX. В тот же период полупроводниковые памяти быстро увеличивались в объёме и снижались в цене. Однако их скорость росла не столь же быстро. Это означало, что время доступа к данным в памяти, в относительном выражении, увеличивалось по сравнению со скоростью процессоров. Это обосновывало необходимость увеличения количества регистров, предоставляя процессору больше временных значений для работы. Увеличение числа регистров требовало большего количества битов в машинном слове для кодирования номера регистра, что, в свою очередь, предполагало сокращение количества самих инструкций для экономии места. Наконец, в работе Эндрю Таненбаума было показано, что 97% всех констант в программе находятся в диапазоне от 0 до 10, причём 0 составляет от 20 до 30% от их общего числа. Кроме того, от 30 до 40% всех значений в программе являются константами, а простые переменные (в отличие от массивов и подобных структур) – ещё от 35 до 40%. Если процессор использует большое машинное слово, например, 32 бита, то в одной инструкции можно закодировать два номера регистров и константу, при условии, что сама инструкция не занимает слишком много битов. Эти наблюдения привели к отказу от ортогональности как основной цели при проектировании процессоров и к появлению философии RISC в 1980-х годах. Процессоры RISC обычно имеют только два режима адресации: прямой (константный) и регистровый. Все остальные режимы, присутствовавшие в более старых процессорах, обрабатываются явно с помощью инструкций загрузки и сохранения, перемещающих данные в регистры и из них. Может быть доступно лишь несколько режимов адресации, и эти режимы могут различаться в зависимости от того, обращается ли инструкция к данным или выполняет передачу управления.