Жмакин А.П. Архитектура ЭВМ (2006) (1186252), страница 33
Текст из файла (страница 33)
□ все операции выполняются за одинаковый промежуток времени (обычно 1 или 2 такта);
Й операнды всех арифметических и логических операций располагаются только в регистрах, к оперативной памяти обращаются только команды загрузки и сохранения;
□ сверхоперативная память представлена большим числом регистров (32—256).
Реализация этих особенностей, с одной стороны, позволяет приблизить работу конвейера к идеальной, с другой стороны — существенно ограничивает возможности системы команд процессора. Действительно, из системы операций исключаются "длинные" операции — умножение, деление, операции над числами с плавающей запятой и др. Исключаются сложные (и эффективные) способы адресации, например, автоиндексные. Это приводит к значительному увеличению длины программ, увеличению времени на выборку команд из памяти, при этом среднее число команд, выполняемых в единицу времени, в RISC-процессорах значительно больше, чем в CISC-процессорах.
По мере совершенствования интегральной технологии появилась возможность ценой значительных аппаратных затрат «(теперь разработчики уже мог-i ли их себе позволить) резко сократить время выполнения "длинных" операций, например, за счет реализации матричного умножителя, табличной арифметики и др. В этом случае длинные операции можно включать в систему команд RISC-процессоров, не нарушая принципов их организации, но увеличивая эффективность системы команд.
В настоящее время понятия "RISC-" и "CISC-архитектура" скорее являются обозначением некоторых принципов проектирования, но не характеристиками конкретных процессоров. Современные процессоры, как правило, реализованы по "гибридному" принципу: содержат ядро RISC, которое выполняет простые и самые распространенные команды за один такт на стадию конвейера, а сложные команды интерпретируются как некая последовательность простых (на уровне микрокоманд). Пользователь же в этом случае имеет дело с системой команд привычной CISC-архитектуры, а внутренние вопросы реализации командного цикла его, как правило, не интересуют.
При реализации конвейеров возникает еще одна проблема, связанная с его оптимальной загрузкой— команды условной передачи управления (в среднем каждая 5—6-я команда программы). Действительно, когда такая команда передается со стадии F на стадию D, на стадию F надо ставить следующую команду, но какую? Условие перехода будет проверено лишь на стадии Е, тогда же определится адрес следующей команды. Здесь возможны два пути решения:
□ приостановить загрузку конвейера до завершения командой перехода стадии Е;
□ загрузить конвейер "наугад" командой по одному из двух возможных адресов, а на стадии Е проверить правильность выбора и, если он оказался неверным — очистить весь конвейер и начать загрузку заново по правильному адресу.
Второй путь представляется предпочтительным, т. к. конвейер не останавливается, и (в среднем) в половине случаев мы избежим потери времени на перезагрузку. Результаты работы конвейера будут еще лучше, если мы научимся правильно предсказывать адрес перехода, чтобы вероятность угадывания адреса приближалась к 1.
В современных процессорах часто предусматривают специальные аппаратные блоки предсказания переходов. В разных процессорах реализуются различные алгоритмы предсказания, основанные на анализе результатов выполнения предыдущих команд переходов [12].
7.5.2. Динамический параллелизм
Один конвейер хорошо, а два лучше? Почему бы, если позволяют ресурсы интегральной технологии, не построить два конвейера и ставить на них одновременно пару команд программы. В процессоре Pentium именно так и сделали— предусмотрели два 5-уровневых конвейера, которые могли работать одновременно и выполнять две целочисленные команды за машинный такт.
Однако возможность одновременной постановки на два разных конвейера пары последовательных команд программы ограничивается рядом условий. Очевидно, что нельзя ставить на разные конвейеры две последовательные команды, если вторая использует в качестве операнда результат работы первой или, во всяком случае, необходимо гарантировать, что к началу стадии выборки операндов второй команды первая (на другом конвейере) уже завершит стадию размещения результата. Существуют и другие ограничения, которые определяют т. н. условия "спаривания" последовательных команд (pairing), позволяющие размещать их одновременно на разных конвейерах.
В процессоре Pentium два конвейера не являются равноправными. Один i них (U) может принять любую команду, а другой (V) — только удовлетв! ряющую условиям "спаривания" (довольно сложным) с командой, поставленной на U. Если эти условия не соблюдаются, следующая команда так же помещается на U-конвейер, а V-конвейер пропускает такт. Некоторые команды могут появляться только на U-конвейере.
Разумеется, производительность двухконвейерного процессора, при прочих равных условиях, превышает производительность одноконвейерного, но далеко не в два раза. Эффективность во многом определяется, насколько часто будут встречаться в программе пары последовательных команд, допускающих "спаривание".
Очевидно, движение в направлении увеличения в процессоре числа конвейе ров, работающих по описанным выше принципам, бесперспективно. Условия "страивания" (если можно так сказать) и т. д. будут настолько сложны, что редко будут выполняться.
Следующим шагом на пути увеличения производительности было решени которое принято называть динамическим параллелизмом, а процессоры, реализующие этот принцип, называют суперскалярными.
Рассмотрим фрагмент программы, написанный на некотором условном языке:
MOV Rl, R4 ADD Rl, @R0 MOV R5, R6 SUB R5, R7 CLR R6
Вторая команда этого фрагмента использует в качестве операнда содержимое ячейки памяти (косвенно-регистровая адресация) и, следовательно, попав на конвейер, будет "тормозить" его' на стадии А. В то же время следующие три команды этого фрагмента никак не связаны с результатами работы второй команды, выполняют действия только над регистрами и могли бы выполняться еще до завершения предыдущей команды, однако в этом случае пришлось бы изменить порядок выполнения команд, определенный программой, чего конвейер не предусматривает.
Суперскалярная архитектура процессора предполагает, что команды (на некотором ограниченном участке программы) могут выполняться не только в порядке их размещения в программе, но и по мере возможности их выполнения независимо от порядка следования. Возможность выполнения определяется, во-первых, отсутствием зависимостей от ранее расположенных, но еще не завершенных команд, во-вторых, наличием свободных ресурсов процессора, необходимых для выполнения команды.
Одним из первых микропроцессоров, реализующих механизм динамического параллелизма, был процессор Pentium Pro (Pentium II) фирмы Intel (рис. 7.15).
На кристалле процессора размещаются два блока кэш-памяти первого уровня, в одном из которых (кэш-С) размещается программа, а в другом (кэш-D) — данные.
Устройство выборки/декодирования выбирает очередную команду из кэш-(в порядке их размещения в программе), при необходимости заменяет ело ные команды на последовательность микрокоманд, снабжает каждую ком ду полем признаков (тегом) и помещает в специальным образом организ ванную память — пул команд.
Устройство диспетчирования постоянно анализирует, с одной стороны, со«| держимое пула команд и выявляет команды, готовые к выполнению на какой-нибудь стадии, с другой стороны — свободные в данный момент операционные устройства. При совпадении "желания" (команда завершила предыдущую стадию и готова к выполнению следующей) и "возможностей" (свободны соответствующие ресурсы) устройство диспетчирования отправляет команду на выполнение независимо от порядка поступления команд в пул. После завершения обработки на очередной стадии команда возвращается в пул с соответствующей пометкой в поле тега.
Устройство отката размещает результаты выполнения команд по адресам назначения. Оно просматривает содержимое пула команд, отыскивает команды, завершившие работу, и извлекает их из пула с размещением результата в строгом соответствии с порядком расположения команд в программе.
Небольшое количество регистров в архитектуре процессоров Intel приводит к интенсивному использованию каждого из них и, как следствие, к возникновению множества мнимых зависимостей между командами, использующими один и тот же регистр. Поэтому, чтобы исключить задержку в выполнении команд из-за мнимых зависимостей, устройство диспетчирования/выпол-нения работает с дублями регистров, находящимися в пуле команд (одному регистру может соответствовать несколько дублей).
Реальный набор регистров контролируется устройством отката, и результаты выполнения команд отражаются на состоянии вычислительной системы только после того, как выполненная команда удаляется из пула команд в соответствии с истинным порядком команд в программе.
Таким образом, принятая в Pentium Pro технология динамического выполнения может быть описана как оптимальное выполнение программы, основанное на предсказании будущих переходов, анализе графа потоков данных с целью выбора наилучшего порядка исполнения команд и на опережающем выполнении команд в выбранном оптимальном порядке. Однако следует иметь в виду, что процессор оптимизирует выполнение только ограниченного участка программы, который в текущий момент располагается в пуле.
Суперскалярная архитектура предполагает наличие на кристалле процессора нескольких параллельно работающих операционных устройств (в т. ч. и нескольких одинаковых). Так, например, RISC-процессор PowerPC содержит шесть параллельно работающих исполнительных устройств: блок предсказа-
Гпава 7. Эволюция архитектур микропроцессоров и микроЭВМ
223
ния ветвлений, два устройства для выполнения простых целочисленных операций (сложение, вычитание, сравнение, сдвиги, логические операции), одно устройство для выполнения сложных целочисленных операций (умножение, деление), устройство обработки чисел с плавающей запятой и блок обращения к внешней памяти. При этом обеспечивается одновременное выполнение четырех команд.
Все операции обработки данных выполняются с регистровой адресацией. При этом для хранения целочисленных операндов используется блок, включающий тридцать два 32-разрядных регистра, а для хранения операндов с плавающей запятой — блок из тридцати двух 64-разрядных регистров.
Выборка данных из памяти производится только командами пересылки, которые выполняются блоком обращения к памяти и осуществляют загрузку данных в регистры или запись их содержимого в память.
При параллельной работе исполнительных устройств возможно их одновременное обращение к одним регистрам. Чтобы избежать ошибок, возникающих при этом в случае записи нового содержимого до того, как другим устройством будет считано предыдущее, введены буферные регистры— 12 для целочисленных регистров и 8 — для регистров с плавающей запятой. Эти регистры служат для промежуточного хранения операндов, дублируя основные регистры блоков, используемые при выполнении текущих операций. После завершения операций производится перезапись полученных результатов в основные регистры (обратная запись).
7.5.3. VLIW-архитектура
Для реализации динамического параллелизма в процессорах с традиционной системой команд и способами компиляции программного кода требуются весьма сложные схемы организации пула, планировщики, схемы "отката" и др. Процессоры такой архитектуры имеют несколько операционных блоков различного, а иногда и одинакового назначения, которые могут работать параллельно, например, 1—2 блока вычисления адресов, 2—3 блока АЛУ для чисел с фиксированной запятой, блок обработки чисел с плавающей запятой, блок размещения результата, блок предсказания переходов и др.
Поскольку процессор может планировать и формировать последовательность выполнения команд на ограниченном (размером пула) участке программы, то для эффективной загрузки операционных блоков требуются не только сложные и эффективные процедуры планирования, но и некоторое "везение" — хорошо, если в пул загружены команды, для выполнения которых нужны различные операционные блоки, а если нет?
Один из путей дальнейшего повышения эффективности подобных систем лежит в области разработки специальных компиляторов, которые упаковывают несколько простых команд в "очень длинное командное слово' (VLIW — аббревиатура от Very Long Instruction Word) таким образом, чтобы в одной "очень длинной команде" можно было использовать все существующие в процессоре операционные блоки. В этом случае командное слово соответствует набору функциональных устройств.