- •Э. Таненбаум
- •Глава 2. Организация компьютерных систем 56
- •Глава 3. Цифровой логический уровень 139
- •Глава 4. Микроархитектурный уровень 230
- •Глава 5. Уровень архитектуры команд 334
- •Глава 6. Уровень операционной системы 437
- •Глава 7. Уровень языка ассемблера 517
- •Глава 8. Архитектуры компьютеров параллельного
- •Глава 9. Библиография 647
- •Глава 8 (архитектура компьютеров параллельного действия) полностью изменена. В ней подробно описываются мультипроцессоры (uma, numa и сома) и мультикомпьютеры (мрр и cow).
- •Глава 1
- •Глава 2 знакомит читателей с основными компонентами компьютера: процессорами, памятью, устройствами ввода-вывода. В ней дается краткое описание системной архитектуры и введение к следующим главам.
- •Глава 2
- •Центральный процессор Центральный процессор
- •12 Битов б
- •24 Входные линии
- •50 Входных линий
- •Глава 4
- •Старший бит
- •Блок выборки команд
- •Сигналы управления
- •Глава 5
- •Intel ia-64
- •Глава 6
- •Глава 7
- •3. Сведения о том, можно ли получить доступ к символу извне процедуры.
- •Глава 8
- •64 Элемента на каждый регистр
- •Intel/Sandia Option Red
- •00 Процессор 2
- •Глава 9
- •4. Mazidi and Mazidi, The 80x86ibm pc and Compatible Computers, 2nd ed.
- •5. McKee et al., Smarter Memory: ImprovingBandwidthforStreamed References.
- •4. McKusick et al., Design and Implementation ofthe 4.4bsd Operating System.
- •3. Hill, Multiprocessors Should Support Simple Memory-Consistency Models.
- •Ieee Scalable Coherent Interface Working Group, ieee, 1989.
- •Ieee Micro Magazine, vol. 18, p. 60-75, July/Aug. 1998b.
- •3Rd ed., Reading, ma: Addison-Wesley, 1998.
- •1988 Int'l. Conf. On Parallel Proc. (Vol. 11), ieee, p. 94-101, 1988.
- •Implementation of the 4.4 bsd Operating System», Reading, ma: Addison-Wesley, 1996.
- •In Shared Memory Multiprocessing», ieee Computer Magazine, vol. 30, p. 4450, Dec. 1997.
- •78Jan.-March 1999.
- •0 123456789Abcdef
- •I и Ijmii him
- •Э. Таненбаум
Intel ia-64
Со временем увеличивать скорость работы IA-32 становилось все сложнее и сложнее. Единственным возможным решением этой проблемы стала разработка совершенно новой архитектуры команд. Новая архитектура, которая разрабатывалась совместно компаниями Intel и Hewlett Packard, получила название IA-64. Это полностью 64-битная машина от начала до конца. Появление полной серии процессоров, в которых реализуется эта архитектура, ожидается в ближайшие годы. Самым первым процессором этого типа был процессор Merced с высокой производительностью, хотя в будущем наверняка появится полный спектр процессоров разного уровня.
Поскольку все, что делает компания Intel, очень важно для компьютерной промышленности, мы подробно рассмотрим архитектуру IA-64. Однако ключевые идеи этой архитектуры уже очень хорошо известны многим исследователям, поэтому они могут отражаться в других разработках. Вообще, некоторые из них уже реализованы в разных формах в экспериментальных системах. В следующих разделах мы изложим, с какой проблемой столкнулась компания Intel, каким образом архитектура IA-64 помогла справиться с этой проблемой и как работают ключевые идеи этого проекта.
Проблема с Pentium II
Основная проблема заключалась в том, что IA-32 — это старая архитектура команд с совершенно не подходящими для современной техники свойствами. Это архитектура CISC с командами разной длины и огромным количеством различных форматов, которые трудно декодировать быстро и на лету. Современная
техника лучше всего работает с архитектурами команд RISC с командами одной длины и с кодом операции фиксированной длины, который легко декодировать. Команды IA-32 можно разбить на микрооперации типа RISC во время выполнения программы, но для этого требуется дополнительное аппаратное обеспечение (пространство на микросхеме), что занимает время и усложняет разработку. Это первый недостаток.
IA-32 — это архитектура, которая ориентирована на двухадресные команды. В настоящее время популярны архитектуры команд типа загрузка/сохранение, где обращение к памяти совершается только в тех случаях, когда нужно поместить операнды в регистры, а все вычисления выполняются с использованием трехадресных регистровых команд. Поскольку скорость работы процессора растет гораздо быстрее, чем скорость работы памяти, положение дел с IA-32 со временем все
больше ухудшается. Это второй недостаток.
Архитектура IA-32 содержит небольшой и нерегулярный набор регистров. Из-за столь малого числа регистров общего назначения (четыре или шесть, в зависимости от того, как считать ESI и EDI) постоянно нужно записывать в память промежуточные результаты, и поэтому приходится делать дополнительные обращения к памяти, даже когда они по логике вещей не нужны. Это третий недостаток.
Из-за недостаточного числа регистров возникает множество ситуаций зависимостей, особенно WAR-зависимостей, поскольку промежуточные результаты нужно куда-то поместить, а дополнительных регистров нет. При недостатке регистров требуется переименование регистров в скрытые регистры. Во избежание слишком частых промахов кэш-памяти команды приходится выполнять не по порядку. Однако семантика архитектуры IA-32 определяет точные прерывания, поэтому команды, выполняемые не по порядку, должны записывать результаты в выходные регистры в строгом порядке. Для всего этого требуется очень сложное аппаратное
обеспечение. Это четвертый недостаток.
Чтобы скорость работы была высокой, нужна сильно конвейеризированная система (12 стадий). Однако это значит, что для выполнения команды потребуется 11 циклов. Следовательно, становится существенным точное предсказание переходов, поскольку в конвейер должны попадать только нужные команды. Но даже при низком проценте неправильных предсказаний существенно снижается производительность. Это пятый недостаток.
Чтобы избежать проблем с неправильным прогнозированием переходов, процессору приходится осуществлять спекулятивное выполнение команд со всеми вытекающими отсюда последствиями. Это шестой недостаток.
Мы не будем перечислять недостатки дальше, поскольку уже сейчас ясно, что за ними кроется реальная проблема. И мы еще не упомянули, что 32-битные адреса архитектуры IA-32 ограничивают размер отдельных программ до 4 Гбайт, а это требование очень сложно выполнять на дорогостоящих серверах с высокой производительностью.
Ситуации с IA-32 можно сравнить с положением в небесной механике как раз перед появлением Коперника. В те времена в астрономии доминировала теория, что Земля является центром Вселенной и неподвижна, а планеты движутся вокруг
нее. Однако новые наблюдения показывали все больше и больше несоответствий
этой теории действительности, и в конце концов теория полностью разрушилась.
Компания Intel находится приблизительно в таком же положении. Огромное количество транзисторов в процессоре Pentium II предназначено для переделывания команд CISC в команды RISC, разрешения конфликтов, прогнозирования переходов, исправления неправильных предсказаний и решения многих других задач подобного рода, оставляя лишь незначительное число транзисторов на долю реальной работы, которая нужна пользователю. Поэтому компания Intel пришла к следующему выводу: нужно выбросить IA-32 и начать все заново (IA-64).
Модель IA-64: открытое параллельное выполнение команд
Первой реализацией архитектуры IA-32 был 64-битный процессор RISC (один из
примеров этого процессора — UltraSPARC II). Поскольку архитектура IA-64 была разработана совместно с компанией Hewlett Packard, в ее основу, несомненно, легла архитектура PA-RISC. Merced — это двухрежимный процессор, который может выполнять и программы IA-32, и программы IA-64, но мы будем говорить только об архитектуре IA-64.
Архитектура IA-64 — это архитектура типа загрузка/сохранение с 64-битными адресами и 64-битными регистрами. Здесь имеется 64 регистра общего назначения, доступных для программ IA-64 (и дополнительные регистры для программ IA-32). Все команды имеют фиксированный формат: код операции, два 6-битных поля для указания входных регистров, одно 6-битное поле для указания выходного регистра и еще одно 6-битное поле, которое мы обсудим позже. Большинство команд берут два регистровых операнда, выполняют над ними какую-нибудь операцию и помещают результат в выходной регистр. Для параллельного выполнения различных операций существует много функциональных блоков. Как видим,
пока ничего необычного в этой архитектуре нет. Большинство RISC-процессоров имеют сходную архитектуру.
А необычной здесь является идея о пучке связанных команд. Команды поступают группами по три штуки (рис. 5.31). Каждая такая группа называется пучком.
Каждый 128-битный пучок содержит три 40-битные команды фиксированного формата и 8-битный шаблон. Пучки могут быть связаны вместе (при этом используется бит конца пучка), поэтому в одном пучке может присутствовать более трех команд. Формат содержит информацию о том, какие команды могут выполняться параллельно. При такой системе и при наличии большого числа регистров компилятор может выделять блоки команд и сообщать процессору, что эти команды можно выполнять параллельно. Таким образом, компилятор должен переупорядочивать команды, проверять, нет ли взаимозависимостей, проверять доступность функциональных блоков и т. д. вместо аппаратного обеспечения. Основная
идея состоит в том, что работа упорядочивания и распределения команд RISC передается от аппаратного обеспечения компилятору. Именно поэтому эта технология называется EPIC (Explicitly Parallel Instruction Computing—технология параллельной обработки команд с явным параллелизмом).
Команды
можно связать
вместе |
Команда 2 |
Команда 3 |
Шаблон |
| |||
Команда 1 |
Команда 2 |
Команда 3 |
Шаблон |
| |||
Команда 1 |
Команда 2 |
Команда 3 |
Шаблон |
|
|
R1 |
R2 |
R3 |
Регистр предиката
Рис. 5.31 . Архитектура IA-64 основана на пучках из трех команд
Есть несколько причин, по которым следует совершать упорядочивание команд во время компиляции. Во-первых, поскольку теперь всю работу выполняет компилятор, аппаратное обеспечение можно сильно упростить, используя миллионы транзисторов для других полезных функций (например, можно увеличить кэшпамять первого уровня). Во-вторых, для любой программы распределение должно производиться только один раз (во время компиляции). В-третьих, поскольку компилятор теперь выполняет всю работу, у поставщика программного обеспечения появится возможность использовать компилятор, который часами оптимизирует свою программу.
Идея пучков команд может быть использована при создании целого семейства процессоров. Процессоры с низкой производительностью могут запускать по одному пучку за цикл. Перед тем как выпустить новый пучок, центральный процессор должен дождаться завершения всех команд. Процессоры с высокой производительностью способны запускать несколько пучков за один цикл (по аналогии с современными суперскалярными процессорами). Кроме того, процессор с высокой производительностью может начать запускать команды из нового пучка еще до того, как закончится выполнение всех команд предыдущего пучка. Естественно, нужно все время проверять, доступны ли нужные регистры и функциональные блоки, но зато вовсе не надо проверять, не будут ли конфликтовать разные команды одного пучка, поскольку компилятор гарантирует, что этого не произойдет.
Предикация
Еще одна особенность архитектуры IA-64 — новый способ обработки условных
переходов. Если бы была возможность избавиться от большинства из них, центральный процессор стал бы гораздо проще и работал бы гораздо быстрее. На первый взгляд может показаться, что устранить условные переходы невозможно, поскольку в программах всегда полно операторов if. Однако в архитектуре IA-64 используется специальная технология, названная предикацией1, которая позволяет сильно сократить их число [10,63]. Ниже мы кратко опишем эту технологию.
От англ. predicate — утверждение, предикат. — Примеч. научн.ред.
В современных машинах все команды являются безусловными в том смысле, что когда центральный процессор натыкается на команду, он просто ее выполняет. Здесь никогда не решается вопрос: «Выполнять или не выполнять?» Напротив, в архитектуре с предикацией команды содержат условия, которые сообщают, в каком случае нужно выполнять команду, а в каком — нет. Именно этот сдвиг от безусловных команд к командам с предикацией позволяет избавиться от многих условных переходов. Вместо того чтобы выбирать ту или иную последовательность безусловных команд, все команды сливаются в одну последовательность команд с предикацией, используя разные предикаты для различных команд.
Чтобы понять, как работает предикация, рассмотрим простой пример (листинги 5.10-5.12), в котором показано условное выполнение команд (условное выполнение — предтеча предикации). В листинге 5.10 мы видим оператор if. В листинге 5.11 мы видим трансляцию этого оператора в три команды: команду сравнения, команду условного перехода и команду перемещения.
Листинг 5.10. Оператор if if (Rl=0)
R2=R3:
Листинг 5.11 . Код на ассемблере для листинга 5.10
CM/P R1.0 BNE L1 МЭ/ R2.R3
L1:
Листинг 5.12. Условная команда CM/OZ R2.R3.R1
В листинге 5.12 мы избавились от условного перехода, используя новую команду СМЖ, которая является условным перемещением. Эта команда проверяет, равен ли третий регистр R1 нулю. Если да, то команда копирует R3 в R2. Если нет, то команда не выполняет никаких действий.
Если у нас есть команда, которая может копировать данные, когда какой-либо регистр равен нулю, значит, у нас может быть и такая команда, которая копирует данные, если какой-нибудь регистр не равен нулю. Пусть это будет команда СМЖ При наличии обеих команд мы уже на пути к полному условному выполнению. Представим оператор if с несколькими присваиваниями в части then и несколькими присваиваниями в части el se. Весь этот кусок программы можно транслировать в код, который будет устанавливать какой-нибудь регистр на 0, если условие не выполнено, и на какое-нибудь другое значение, если условие выполнено. Следуя установке регистров, присваивания в части then можно скомпилировать в последовательность команд СМЗЭД а присваивания в части el se — в последовательность команд СМЖ
Все эти команды, регистровая установка, СМЖ и СМЖ формируют единый основной блок без условных переходов. Команды можно даже переупорядочить при компиляции или во время выполнения программы. Единственное требование при этом состоит в том, чтобы условие было известно к тому моменту, когда условные команды уже нужно помещать в выходные регистры (то есть где-то в конце конвейера). Простой пример куска программы с then и el se приведен в листингах 5.13-5.15.
Листинг 5.13. Оператор if
if(Rl = 0) {
R2=R3;
R4=R5;
} else {
R6=R7:
R8=R9:
}
Листинг 5.14. Код на ассемблере для листинга 5.13
CMP R1.0 BNE L1 MOV R2.R3 MOV R4.R5 BR L2 LI: MOV R6.R7
MOV R8.R9
L2:
Листинг 5.15. Условное выполнение
CMOZ R2.R3.R1 CMOZ R4.R5.R1 CMON R6.R7.R1 CMON R8.R9.R1
Мы показали только очень простые условные команды (взятые из Pentium II), но в архитектуре IA-64 все команды предикатны. Это значит, что выполнение каждой команды можно сделать условным. Дополнительное 6-битное поле, о котором мы упомянули выше, выбирает один из 64 1-битных предикатных регистров. Следовательно, оператор i f может быть скомпилирован в код, который устанавливает один из предикатных регистров на 1, если условие истинно, и на 0, если условие ложно. Одновременно с этим данное поле автоматически устанавливает другой предикатный регистр на обратное значение. При использовании предикации машинные команды, которые формируют операторы then и el se, будут сливаться в единый поток команд, первый из них — с использованием предиката, а второй — с использованием его обратного значения.
Листинги 5.16-5.18 показывают, как можно использовать предикацию для устранения переходов. Команда CMtlQ) сравнивает два регистра и устанавливает предикатный регистр Р4 на 1, если они равны, и на 0, если они не равны. Кроме того, команда устанавливает парный регистр, например Р5, на обратное условие. Теперь команды частей i f и then можно поместить одну за другой, причем каждая из них связывается с каким-нибудь предикатным регистром (регистр указывается в угловых скобках). Сюда можно поместить любой код, при условии что каждая команда предсказывается правильно.
Листинг 5.16. Оператор if
if(Rl==R2)
R3=R4+R5:
Else
R6=R4-R5
Листинг 5.17. Код на ассемблере для листинга 5.16
CMP R1.R2
BNE L1
MOV R3.R4 ADD R3.R5
BR L2
LI: MOV R6.R4 SUB R6.R5
L2:
Листинг 5.18. Выполнение с предикацией
CMPEQ R1.R2.P4
<Р4> ADD R3.R4.R5 <Р5> SUB R6.R4.R5
В архитектуре IA-64 эта идея доведена до логического конца: здесь с предикатными регистрами связаны и команды сравнения, и арифметические команды, а также некоторые другие команды, выполнение которых зависит от какого-либо предикатного регистра. Команды с предикацией могут помещаться в конвейер последовательно без каких-либо проблем и простаиваний. Поэтому они очень полезны.
В архитектуре IA-64 предикация происходит следующим образом. Каждая команда действительно выполняется, и в самом конце конвейера, когда уже нужно сохранять результат в выходной регистр, производится проверка, истинно ли предсказание. Если да, то результаты просто записываются в выходной регистр. Если предсказание ложно, то записи в выходной регистр не происходит. Подробно о предикации вы можете прочитать в книге [34].
Спекулятивная загрузка
Еще одна особенность IA-64 — наличие спекулятивной загрузки. Если команда LOAD спекулятивна и оказывается ложной, то вместо того чтобы вызвать исключение (exception), она просто останавливается и сообщает, что регистр, с которым она связана, недействителен. Если этот регистр будет использоваться позднее, то произойдет исключение (exception).
Компилятор должен перемещать команды LOAD в более ранние позиции относительно других команд с тем, чтобы они выполнялись еще до того, как они понадобятся. Поскольку выполнение этих команд начинается раньше, чем нужно, они могут завершиться еще до того, как потребуются результаты. Компилятор вставляет команду CHECK в том месте, где ему нужно получить значение определенного регистра. Если значение там уже есть, команда CHECK работает как NOP, и выполнение программы сразу продолжается дальше. Если значения в регистре еще нет, следующая команда должна простаивать.
Итак, машина с архитектурой IA-64 имеет несколько источников повышения
скорости. Во-первых, это современная конвейеризированная трехадресная машина RISC типа загрузка/сохранение. Во-вторых, компилятор определяет, какие команды могут выполняться одновременно, не вступая в конфликт, и группирует эти команды в пучки. Таким образом, процессор может просто распределять пучок, не совершая никаких проверок. В-третьих, предикация позволяет сливать команды обоих переходов от оператора if, устраняя при этом условный переход, а также и само прогнозирование этого перехода. Наконец, спекулятивная загрузка позволяет вызывать операнды заранее, и даже если позднее окажется, что эти операнды не нужны, ничего страшного не произойдет.
Проверка в реальных условиях
Если все эти нововведения функционируют, процессор Merced действительно будет чрезвычайно мощным. Однако здесь нужно высказать несколько предостережений. Во-первых, такая продвинутая машина никогда не создавалась раньше. История показывает, что грандиозные планы часто не удается осуществить по самым разным причинам.
Во-вторых, придется составлять компиляторы для IA-64. А составление хорошего компилятора для IA-64 — дело очень сложное. Кроме того, многочисленные исследования в параллельном программировании, проведенные за последние 30 лет, оказались не очень успешными. Если в программе есть какой-то параллелизм или если компилятор не может извлечь его, все пучки команд в архитектуре IA-64 будут короткими, а от этого большого увеличения производительности не произойдет.
В-третьих, для реализации этой идеи должна существовать полностью 64-битная операционная система. Windows 95 и Windows 98 такими системами не являются и вряд ли когда-нибудь будут. Это значит, что всем придется перейти на
Windows NT или UNIX, и такой переход не будет безболезненным. Спустя 10 лет с момента появления 32-битного процессора 386 система Windows 95 все еще содержала множество 16-битных команд и никогда не использовала аппаратное обеспечение с сегментацией, которое около 10 лет включается во все процессоры Intel (сегментацию мы будем обсуждать в главе 6). Сколько времени потребуется на то, чтобы операционные системы стали полностью 64-битными, никто не знает.
В-четвертых, многие будут судить об архитектуре IA-64 по тому, как на ней будут работать старые 16-битные игры MS DOS. Когда появился Pentium Pro, он не пользовался особенным успехом, поскольку старые 16-битные программы работали на нем с такой же скоростью, как и на обычной машине Pentium. Поскольку старые
16-битные (и 32-битные) программы не будут использовать новые особенности
процессоров IA-64, никакие предикатные регистры им не помогут. Людям придется приобретать средства наращивания для своего программного обеспечения, подходящие для новых компиляторов типа IA-64. Многие из них будут очень дорогими.
Наконец, другие производители (включая Intel) могут выпустить альтернативные варианты, которые будут давать высокую производительность, используя при этом более привычные архитектуры RISC, возможно, с большим количеством условных команд. Более высокоскоростные версии Pentium II также будут серьезным соперником для IA-64. Вероятно, пройдет очень много лет, прежде чем IA-64 будет доминировать на компьютерном рынке, подобно архитектуре IA-32.
Краткое содержание главы
Для большинства людей уровень архитектуры команд — это «машинный язык».
На этом уровне машина имеет память с байтовой организацией или с пословной
организацией, состоящую из нескольких десятков мегабайтов и содержащую такие команды, как MLXE, ЯЮ и BEQ.
В большинстве современных компьютеров память организована в виде последовательности байтов, при этом 4 или 8 байтов группируются в слова. Обычно в машине имеется от 8 до 32 регистров, каждый из которых содержит одно слово.
Команды обычно имеют 1,2 или 3 операнда, обращение к которым происходит с помощью различных способов адресации: непосредственной, прямой, регистровой, индексной и т. д. Команды обычно могут перемещать данные, выполнять унарные и бинарные операции (в том числе арифметические и логические), совершать переходы, вызывать процедуры, осуществлять циклы, а иногда и выполнять некоторые операции ввода-вывода. Типичные команды перемещают слово из памяти в регистр или наоборот, складывают, вычитают, умножают или делят два регистра или регистр и слово из памяти, или сравнивают два значения в регистрах или памяти. Обычно в компьютере содержится не более 200 команд.
Для осуществления передачи управления на втором уровне используется ряд элементарных действий: переходы, вызовы процедур, вызовы сопрограмм, ловушки и прерывания. Переходы нужны для того, чтобы остановить одну последовательность команд и начать новую. Процедуры нужны для того, чтобы изолировать какой-то блок программы, который можно вызывать из различных мест этой же программы. Сопрограммы позволяют двум потокам управления работать одновременно. Ловушки используются для сообщения об исключительных ситуациях (например, о переполнении). Прерывания позволяют осуществлять процесс ввода-вывода параллельно с основным вычислением, при этом центральный процессор получает сигнал, как только ввод-вывод завершен.
Задачу «Ханойская башня» можно решить с использованием рекурсии.
Наконец, архитектура IA-64 использует модель вычисления EPIC. Для повышения скорости работы в этой архитектуре предусмотрены предикация и спекулятивная загрузка. IA-64 может иметь значительное преимущество над Pentium II, но она возлагает на компилятор огромное бремя параллелизма.
Вопросы и задания
В Pentium II команды могут содержать любое число байтов, даже нечетное. В UltraSPARC II все команды содержат четное число байтов. В чем преимущество системы Pentium II?
Разработайте расширенный код операций, который позволяет закодировать в 36-битной команде следующее:
7 команд с двумя 32-битными адресами и номером одного 3-битного регистра;
500 команд с одним 15-битным адресом и номером одного 3-битного регистра;
50 команд без адресов и регистров.
3. Можно ли разработать такой расширенный код операций, который позво- лял бы кодировать в 12-битной команде следующее:
4 команды с тремя регистрами;
255 команд с одним регистром;
16 команд без регистров. (Размер регистра составляет 3 бита.)
В некоторой машине имеются 16-битные команды и 6-битные адреса. Одни команды содержат один адрес, другие — два. Если существует п двухадресных команд, то каково максимальное число одноадресных команд?
Имеется одноадресная машина с регистром-аккумулятором. Ниже приведены значения некоторых слов в памяти:
слово 20 содержит число 40; + слово 30 содержит число 50;
слово 40 содержит число 60;
слово 50 содержит число 70.
Какие значения следующие команды загрузят в регистр-аккумулятор?
LOAD IMMEDIATE 20
LOAD DIRECT 20
LOAD INDIRECT 20
LOAD IMMEDIATE 30
LOAD DIRECT 30
LOAD INDIRECT 30.
6. Для каждого из четырех видов машин — безадресной, одноадресной, двух- адресной и трехадресной — напишите программу вычисления следующего выражения:
X=(A+BxC)/(D-ExF).
7. В наличии имеются следующие команды:
• безадресные: PUSH М
POP М
ADD
SUB
MUL
DIV
• одноадресные: KAD M
STORE M ADD M
SUB М MUL М DIV М + двухадресные: MOV (X=Y) ADD (X=X+Y) SUB (X=X-Y) MUL (X=X*Y) DIV (X=X/Y)
• трехадресные: МУ (X=Y)
ADD (X=Y+Z) SUB (X=Y-Z) MUL (X=Y*Z) DIV (X=Y/Z).
M — это 16-битный адрес памяти, а X, Y и Z — это или 16-битные адреса, или 4-битные регистры. Безадресная машина использует стек, одноадресная машина использует регистр-аккумулятор, а оставшиеся две имеют 16 регистров и команды, которые оперируют со всеми комбинациями ячеек памяти и регистров. Команда SUB X, Y вычитает Y из X, а команда SIB X, Y, Z вычитает Z из Y и помещает результат в X. Если длина кодов операций равна 8 битам, а размеры команд кратны 4 битам, сколько битов нужно каждой машине для вычисления X?
Придумайте такой механизм адресации, который позволяет определять в 6-битном поле произвольный набор из 64 адресов, не обязательно смежных.
В чем недостаток самоизменяющихся программ, которые не были упомянуты в тексте?
Переделайте следующие формулы из инфиксной записи в обратную польскую запись:
A+B+C+D+E
(А+В) х (C+D)+E
(AxB)+(CxD)+E
(А-В) х (((C-DxE)/F)/G) xH
12. Переделайте следующие формулы из обратной польской записи в инфикс- ную запись:
•AB+C+Dx
AB/CD/ +
ABCDE+xx/
ABCDExF/+G-H/x+
13. Какие из следующих пар формул в обратной польской записи математичес- ки эквивалентны?
• АВ + С + иАВС + +
• АВ-С-иАВС--
• АВхС+иАВС+х
Напишите три формулы в обратной польской записи, которые нельзя переделать в инфиксную запись.
Переделайте следующие инфиксные логические формулы в обратной
польской записи.
(А И В) ИЛИ С
(А ИЛИ В) И (А ИЛИ С)
(А И В) ИЛИ (С И D)
16. Переделайте следующую инфиксную формулу в обратную польскую запись
и напишите код JVM, чтобы выполнить ее. (2хЗ+4)-(4/2+1)
17. Команда языка ассемблера
MJVREGADDR
означает загрузку регистра из памяти компьютера Pentium II. Однако для UltraSPARC II для загрузки регистра из памяти нужно написать
LOAD ADDR, REG
Почему порядок операндов разный?
Сколько регистров содержится в машине, форматы команд которой даны на рис. 5.16?
В форматах команд на рис. 5.16 бит 23 используется для различения формата 1 и формата 2. Однако для определения формата 3 никакого специального бита не предусмотрено. Как аппаратное обеспечение узнает, что нужно
использовать формат 3?
Обычно программа определяет местонахождение переменной X в пределах интервала от А до В. Если бы имелась трехадресная команда с операндами А, В и X, сколько битов кода условия было бы установлено этой командой?
Pentium II содержит бит кода условия, который следит за переносом бита 3 после выполнения арифметической операции. Зачем это нужно?
В UltraSPARC II нет такой команды, которая загружает в регистр 32-битное число. Вместо нее обычно используется последовательность из двух
команд: SETHI и ADD. Существуют ли еще какие-нибудь способы загрузки 32-битного числа в регистр? Аргументируйте.
23. Один из ваших друзей стучится к вам в комнату в 3 часа ночи и радостно сообщает, что у него появилась замечательная идея: команда с двумя кодами операций. Что вы сделаете в этой ситуации: отправите своего друга полу- чать патент или пошлете его обратно к чертежной доске?
Вопросы и задания 435
24. В программировании очень распространены следующие формы проверки:
if (n==0) if O>J). if (k<4).
Предложите команду, которая будет проверять эти условия эффективно.
Какие поля имеются в вашей команде?
25. Покажите для 16-битного двоичного числа 1001 0101 1100 0011: + Сдвиг вправо на 4 бита с заполнением нулями.
Сдвиг вправо на 4 бита с расширением по знаку.
Сдвиг влево на 4 бита.
Циклический сдвиг влево на 4 бита.
Циклический сдвиг вправо на 4 бита.
Как можно в машине, в которой нет команды CLR очистить слово памяти?
Вычислите логическое выражение (А И В) ИЛИ С для:
А-1101 0000 1010 1101
В—1111 11110000 1111
С=0000 0000 0010 0000
28. Придумайте, как поменять местами две переменные А и В, не используя при
этом третью переменную или регистр. Подсказка: подумайте о команде ИСКЛЮЧАЮЩЕЕ ИЛИ.
На некотором компьютере можно перемещать число из одного регистра в другой, сдвигать каждый из них влево на разное количество байтов и складывать полученные результаты за меньшее время, чем потребовалось бы для выполнения умножения. При каком условии эта последовательность команд будет полезна для вычисления произведения «константа х переменная»?
Разные машины имеют разную плотность команд (то есть разное число байтов, которое требуется для выполнения определенного вычисления). Транслируйте следующие три фрагмента программы на языке Java на ассемблер для Pentium II, UltraSPARC II и JVM. Затем посчитайте, сколько байтов требуется для выполнения каждого выражения для каждой машины (предполагается, что i и j — это локальные переменные памяти):
i-3;
i-j;
В этой главе рассматривались команды цикла для работы с циклами for. Разработайте команду для обращения с циклами while.
Предположим, что ханойские монахи могут перемещать один диск за 1 минуту (они не торопятся закончить работу, поскольку в Ханое очень мало
вакансий для людей с подобными навыками). Сколько времени им потребуется, чтобы решить задачу (то есть переместить все 64 диска)? Ответ
дайте в годах.
Почему устройства ввода-вывода помещают вектор прерывания на шину? Разве нельзя вместо этого сохранить соответствующую информацию в таблице в памяти?
Компьютер для считывания информации с диска использует канал прямого доступа к памяти. Диск содержит 64 сектора по 512 байтов на дорожке. Время оборота диска 16 мс. Ширина шины 16 битов. Каждая передача шины занимает 500 не. В среднем для одной команды процессора требуется два цикла шины. Насколько скорость работы процессора замедляется из-за прямого доступа к памяти?
Почему программам обработки прерываний приписываются определенные приоритеты, а обычные процедуры приоритетов не имеют?
Архитектура IA-64 содержит необычайно большое число регистров (64).
Связано ли столь большое количество регистров с использованием предикации? Если да, то каким образом? Если нет, то зачем тогда их так много?
В пятой главе обсуждалось понятие спекулятивной загрузки. Но о командах спекулятивного сохранения мы не упоминали. Почему? Может быть, они просто аналогичны спекулятивным загрузкам, или существует какая-то другая причина, по которой мы не стали о них говорить?
Когда нужно связать две локальные сети, между ними помещается мост, связанный с обеими сетями. Каждый передаваемый какой-либо сетью пакет
вызывает прерывание на мосту, чтобы мост мог определить, нужно ли этот пакет пересылать. Предположим, что на обработку прерывания и проверку пакета требуется 250 мке, но пересылка этого пакета в случае необходимости совершается с использованием прямого доступа в память, поэтому центральный процессор не загружается. Если все пакеты вмещают 1 Кбайт, то какова максимальная скорость передачи данных на каждой из сетей?
39. На рис. 5.24 указатель фрейма указывает на первую локальную переменную. Какая информация нужна программе, чтобы выйти из процедуры и вернуться
в исходное положение?
Напишите подпрограмму на языке ассемблера для превращения целого двоичного числа со знаком в код ASCII.
Напишите подпрограмму на языке ассемблера для превращения инфиксной формулы в обратную польскую запись.
«Ханойская башня» — это не единственная рекурсивная процедура, любимая многими компьютерщиками. Есть еще одна очень популярная рекурсивная процедура п!, где n!=n(n-l)! Подчиняется ограничивающему условию 01=1. Напишите на вашем любимом языке ассемблера процедуру для вычисления п!.
Попробуйте решить задачу «Ханойская башня» без использования рекурсии путем содержания стека в массиве. Предупреждаем, что, вероятно, вы не сможете найти решения.