
- •Спекулятивная загрузка
- •Краткое содержание главы
- •Вопросы и задания
- •Глава 6
- •Виртуальная память
- •Страничная организация памяти
- •Реализация страничной организации памяти
- •Вызов страниц по требованию и рабочее множество
- •Политика замещения страниц
- •Размер страниц и фрагментация
- •Сегментация
- •Реализация сегментации
- •Виртуальная память Pentium 4
- •Виртуальная память UltraSparc III
- •Виртуальная память и кэширование
- •Виртуальные команды ввода-вывода
- •Реализация виртуальных команд ввода-вывода
- •Команды управления каталогами
- •Виртуальные команды для параллельной работы
- •Формирование процесса
- •Состояние гонок
- •Синхронизация процесса с использованием семафоров
- •Краткое содержание главы
- •Вопросы и задания
- •Уровень ассемблера
- •Знакомство с ассемблером
- •Макросы
- •Процесс ассемблирования
- •Компоновка и загрузка
- •Глава 8
- •Параллельные компьютерные архитектуры
Виртуальная
память
мент программы можно транслировать в код, который будет устанавливать какой-нибудь регистр на 0, если условие не выполнено, и на какое-нибудь другое значение, если условие выполнено. Таким образом, присваивания в части then можно скомпилировать в последовательность команд CM0VN, а присваивания в части el se — в последовательность команд CM0VZ.
Все эти команды, в том числе команды установки регистров, CN0VN и CM0VZ, формируют единый основной блок без условных переходов. Команды можно даже переупорядочить при компиляции или во время выполнения программы. Единственное требование состоит в том, чтобы условие было известно к тому моменту, когда условные команды потребуется помещать в выходные регистры (то есть где-то в конце конвейера). Простой пример фрагмента программы с операторами then и else приведен в листингах 5.12-5.14.
Листинг 5.12, Оператор if
if(Rl == 0) {
R2 = R3;
R4 = R5;
} else {
R6 = R7;
R8 - R9;
}
Листинг 5.13. Код на ассемблере для листинга 5.12
CMP R1.0 BNE L1 MOV R2.R3 MOV R4.R5 BR L2 LI: MOV R6.R7
MOV R8.R9
L2:
Листинг 5.14. Условное выполнение
CMOVZ R2.R3.R1 CMOVZ R4.R5.R1 CMOVN R6.R7.R1 CMOVN R8.R9.R1
Мы показали только очень простые условные команды (взятые из архитектуры команд Pentium 4), но в архитектуре IA-64 все команды предикатные. Это значит, что выполнение каждой команды можно сделать условным. Дополнительное 6-разрядное поле предикатного регистра, о котором мы упомянули, позволяет выбрать один из 64 1-разрядных предикатных регистров. Следовательно, оператор If может быть скомпилирован в код, который устанавливает один из предикатных регистров в 1, если условие истинно, и в 0, если условие ложно. Одновременно и автоматически инвертируется другой предикатный регистр. Таким образом, при поддержке предикации машинные команды, которые формируются из операторов then и el se, сливаются в единый поток команд, причем у команд первого из них поле предикатного регистра оказывается единичным, у второго — нулевым.
В листингах 5.15-5.17 показано, как использовать предикацию для устранения переходов. Команда CMPEQ сравнивает два регистра и устанавливает предикатный регистр Р4 в 1, если они равны, и в 0, если они не равны. Кроме того, команда инвертирует еще один регистр, например, Р5. После этого команды частей if и then можно поместить одну за другой, причем каждая из них оказывается связанной с каким-нибудь предикатным регистром (регистр указывается в угловых скобках). Сюда можно поместить любой код, при условии, что каждая команда предсказывается правильно.
Листинг 5-15, Оператор if
if(Rl == R2)
R3 = R4 + R5;
Else
R6 - R4 - R5
Листинг 5-16- Код на ассемблере для листинга 5.15
CMP R1.R2 BNE L1 MOV R3.R4 ADD R3.R5 BR L2 LI: MOV R6.R4
SUB R6.R5
L2:
Листинг 5-17- Предикатное выполнение
CMPEQ R1.R2.P4 <P4> ADD R3.R4.R5 <P5> SUB R6.R4.R5
В архитектуре IA-64 эта идея доведена до логического завершения — здесь с предикатными регистрами связаны и команды сравнения, и арифметические команды, и некоторые другие команды. Предикатные команды могут помещаться в конвейер последовательно без каких-либо проблем и простоев. Поэтому они очень полезны.
В архитектуре IA-64 предикация происходит следующим образом. Каждая команда действительно выполняется, и в самом конце конвейера, когда уже нужно сохранять результат в выходном регистре, производится проверка, истинно ли предсказание. Если да, то результаты просто записываются в выходной регистр. Если предсказание ложно, то записи в выходной регистр не происходит. Подробно о предикации вы можете прочитать в дополнительной литературе [60].
Спекулятивная загрузка
Еще одна особенность IA-64, повышающая быстродействие, — поддержка спекулятивной загрузки. Если команда LOAD спекулятивна и не срабатывает, то вместо того, чтобы вызвать исключение, она просто прекращает выполняться и сообщает, что регистр, в который она должна была загрузить значение, недействителен. Для этого используется тот самый бит отравления, о котором мы упоминали в главе 4. А исключение будет вызвано только в том случае, если затем попытаться использовать этот регистр.
Обычно при спекулятивной загрузке компилятор помещает команды LOAD перед другими командами. Поскольку выполнение этих команд начинается раньше, чем нужно, они могут завершиться еще до того, как потребуются результаты. В том месте, где ему нужно получить значение определенного регистра, компилятор вставляет команду CHECK. Если значение там уже есть, команда CHECK работает так же, как N0P, и выполнение программы просто сразу продолжается дальше. Если значения в регистре еще нет, следующая команда вынуждена простаивать.
Суммируя, можно сказать, что в машинах с архитектурой IA-64 реализовано несколько механизмов повышения быстродействия. Во-первых, это современная конвейеризированная трехадресная RISC-машина, поддерживающая механизм загрузки/сохранения. Во-вторых, компилятор определяет, какие команды могут выполняться одновременно, и, не вступая в конфликт, группирует эти команды в пучки. Таким образом, процессор может просто планировать обработку пучков, не думая ни о каких проверках. В-третьих, предикация позволяет объединить команды обоих переходов в операторе i f, устраняя при этом как условный переход, так и необходимость прогнозирования этого перехода. Наконец, спекулятивная загрузка позволяет вызывать операнды заранее, и даже если позднее окажется, что эти операнды не нужны, ничего страшного не произойдет.
Дополнительные сведения о процессоре Itanium 2 и его микроархитектуре можно почерпнуть в дополнительной литературе [144, 178].
Краткое содержание главы
Для большинства людей уровень архитектуры набора команд — это «машинный язык». На этом уровне машина имеет память с байтовой или пословной организацией, состоящую из нескольких десятков мегабайтов и содержащую команды наподобие MOVE, ADD и BEQ.
В большинстве современных компьютеров память организована в виде последовательности байтов, при этом 4 или 8 байт группируются в слова. Обычно в машине есть от 8 до 32 регистров, каждый из которых содержит одно слово. В некоторых машинах (например, в Pentium 4) при обращении к словам памяти выравнивание по естественным границам ячеек не требуется, в других (например, в UltraSPARC III) это — обязательное условие.
Команды обычно имеют 1, 2 или 3 операнда, обращение к которым происходит с помощью различных режимов адресации: непосредственной, прямой, регистровой, индексной и т. д. Команды обычно могут перемещать данные, выполнять унарные и бинарные операции (в том числе арифметические и логические), совершать переходы, вызывать процедуры, выполнять циклы, а иногда и некоторые операции ввода-вывода. Типичные команды перемещают слово из памяти в регистр или наоборот, складывают, вычитают, умножают или делят два регистра или регистр и слово из памяти, или сравнивают два значения в регистрах или памяти. Довольно часто количество команд в компьютерах превышает 200. В CISC-процессорах их и того больше.
Для передачи управления на уровне архитектуры команд используются различные примитивы: перехода, вызовов процедур и сопрограмм, перехвата исключений и обработки прерываний. Переходы нужны для того, чтобы остановить одну последовательность команд и начать новую. Процедуры позволяют выделить какой-то фрагмент программы, который можно затем вызывать из различных мест этой же программы. Сопрограммы позволяют двум потокам управления работать параллельно. Перехват исключений используется для сигнализации об исключительных ситуациях (например, о переполнении). Механизм прерываний дает возможность выполнять ввод-вывод параллельно с основными вычислениями, при этом, как только ввод-вывод завершается, центральный процессор получает сигнал об этом.
Задачу «Ханойская башня» можно решить с использованием рекурсии.
Наконец, в архитектуре IA-64 используется вычислительная модель EPIC, упрощающая реализацию параллелизма в программах. Для повышения быстродействия в этой архитектуре предусмотрены группировка команд, предикация и спекулятивная загрузка. Архитектура IA-64 способна стать удачной заменой Pentium 4, даже несмотря на то, что она возлагает на компилятор большую нагрузку в плане поддержания параллелизма.