Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебник Архитектура компьютера. Э. Таненбаум..doc
Скачиваний:
111
Добавлен:
20.06.2014
Размер:
7.54 Mб
Скачать

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—технология парал­лельной обработки команд с явным параллелизмом).

Команды можно

связать вместе

Команда 1

Команда 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, но она возлагает на компилятор огромное бремя параллелизма.

Вопросы и задания

  1. В Pentium II команды могут содержать любое число байтов, даже нечетное. В UltraSPARC II все команды содержат четное число байтов. В чем преиму­щество системы Pentium II?

  2. Разработайте расширенный код операций, который позволяет закодировать в 36-битной команде следующее:

  • 7 команд с двумя 32-битными адресами и номером одного 3-битного регистра;

  • 500 команд с одним 15-битным адресом и номером одного 3-битного регистра;

  • 50 команд без адресов и регистров.

3. Можно ли разработать такой расширенный код операций, который позво- лял бы кодировать в 12-битной команде следующее:

  • 4 команды с тремя регистрами;

  • 255 команд с одним регистром;

  • 16 команд без регистров. (Размер регистра составляет 3 бита.)

  1. В некоторой машине имеются 16-битные команды и 6-битные адреса. Одни команды содержат один адрес, другие — два. Если существует п двухадрес­ных команд, то каково максимальное число одноадресных команд?

  2. Имеется одноадресная машина с регистром-аккумулятором. Ниже приве­дены значения некоторых слов в памяти:

  • слово 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).

  1. M — это 16-битный адрес памяти, а X, Y и Z — это или 16-битные адреса, или 4-битные регистры. Безадресная машина использует стек, одноадресная ма­шина использует регистр-аккумулятор, а оставшиеся две имеют 16 регист­ров и команды, которые оперируют со всеми комбинациями ячеек памяти и регистров. Команда SUB X, Y вычитает Y из X, а команда SIB X, Y, Z вычитает Z из Y и помещает результат в X. Если длина кодов операций равна 8 битам, а размеры команд кратны 4 битам, сколько битов нужно каждой машине для вычисления X?

  2. Придумайте такой механизм адресации, который позволяет определять в 6-битном поле произвольный набор из 64 адресов, не обязательно смежных.

  3. В чем недостаток самоизменяющихся программ, которые не были упомяну­ты в тексте?

  4. Переделайте следующие формулы из инфиксной записи в обратную польскую запись:

  • 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. Какие из следующих пар формул в обратной польской записи математичес- ки эквивалентны?

• АВ + С + иАВС + +

• АВ-С-иАВС--

• АВхС+иАВС+х

  1. Напишите три формулы в обратной польской записи, которые нельзя пере­делать в инфиксную запись.

  2. Переделайте следующие инфиксные логические формулы в обратной

польской записи.

  • (А И В) ИЛИ С

  • (А ИЛИ В) И (А ИЛИ С)

  • (А И В) ИЛИ (С И D)

16. Переделайте следующую инфиксную формулу в обратную польскую запись

и напишите код JVM, чтобы выполнить ее. (2хЗ+4)-(4/2+1)

17. Команда языка ассемблера

MJVREGADDR

означает загрузку регистра из памяти компьютера Pentium II. Однако для UltraSPARC II для загрузки регистра из памяти нужно написать

LOAD ADDR, REG

Почему порядок операндов разный?

  1. Сколько регистров содержится в машине, форматы команд которой даны на рис. 5.16?

  2. В форматах команд на рис. 5.16 бит 23 используется для различения форма­та 1 и формата 2. Однако для определения формата 3 никакого специально­го бита не предусмотрено. Как аппаратное обеспечение узнает, что нужно

использовать формат 3?

  1. Обычно программа определяет местонахождение переменной X в пределах интервала от А до В. Если бы имелась трехадресная команда с операндами А, В и X, сколько битов кода условия было бы установлено этой командой?

  2. Pentium II содержит бит кода условия, который следит за переносом бита 3 после выполнения арифметической операции. Зачем это нужно?

  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 бита.

  1. Как можно в машине, в которой нет команды CLR очистить слово памяти?

  2. Вычислите логическое выражение (А И В) ИЛИ С для:

  • А-1101 0000 1010 1101

  • В—1111 11110000 1111

  • С=0000 0000 0010 0000

28. Придумайте, как поменять местами две переменные А и В, не используя при

этом третью переменную или регистр. Подсказка: подумайте о команде ИСКЛЮЧАЮЩЕЕ ИЛИ.

  1. На некотором компьютере можно перемещать число из одного регистра в дру­гой, сдвигать каждый из них влево на разное количество байтов и склады­вать полученные результаты за меньшее время, чем потребовалось бы для выполнения умножения. При каком условии эта последовательность команд будет полезна для вычисления произведения «константа х переменная»?

  2. Разные машины имеют разную плотность команд (то есть разное число бай­тов, которое требуется для выполнения определенного вычисления). Транс­лируйте следующие три фрагмента программы на языке Java на ассемблер для Pentium II, UltraSPARC II и JVM. Затем посчитайте, сколько байтов требуется для выполнения каждого выражения для каждой машины (пред­полагается, что i и j — это локальные переменные памяти):

  • i-3;

  • i-j;

  1. В этой главе рассматривались команды цикла для работы с циклами for. Разработайте команду для обращения с циклами while.

  2. Предположим, что ханойские монахи могут перемещать один диск за 1 ми­нуту (они не торопятся закончить работу, поскольку в Ханое очень мало

вакансий для людей с подобными навыками). Сколько времени им по­требуется, чтобы решить задачу (то есть переместить все 64 диска)? Ответ

дайте в годах.

  1. Почему устройства ввода-вывода помещают вектор прерывания на шину? Разве нельзя вместо этого сохранить соответствующую информацию в таб­лице в памяти?

  2. Компьютер для считывания информации с диска использует канал прямого доступа к памяти. Диск содержит 64 сектора по 512 байтов на дорожке. Вре­мя оборота диска 16 мс. Ширина шины 16 битов. Каждая передача шины занимает 500 не. В среднем для одной команды процессора требуется два цикла шины. Насколько скорость работы процессора замедляется из-за пря­мого доступа к памяти?

  3. Почему программам обработки прерываний приписываются определенные приоритеты, а обычные процедуры приоритетов не имеют?

  4. Архитектура IA-64 содержит необычайно большое число регистров (64).

Связано ли столь большое количество регистров с использованием преди­кации? Если да, то каким образом? Если нет, то зачем тогда их так много?

  1. В пятой главе обсуждалось понятие спекулятивной загрузки. Но о коман­дах спекулятивного сохранения мы не упоминали. Почему? Может быть, они просто аналогичны спекулятивным загрузкам, или существует какая-то другая причина, по которой мы не стали о них говорить?

  2. Когда нужно связать две локальные сети, между ними помещается мост, свя­занный с обеими сетями. Каждый передаваемый какой-либо сетью пакет

вызывает прерывание на мосту, чтобы мост мог определить, нужно ли этот пакет пересылать. Предположим, что на обработку прерывания и проверку пакета требуется 250 мке, но пересылка этого пакета в случае необходимос­ти совершается с использованием прямого доступа в память, поэтому цент­ральный процессор не загружается. Если все пакеты вмещают 1 Кбайт, то какова максимальная скорость передачи данных на каждой из сетей?

39. На рис. 5.24 указатель фрейма указывает на первую локальную переменную. Какая информация нужна программе, чтобы выйти из процедуры и вернуться

в исходное положение?

  1. Напишите подпрограмму на языке ассемблера для превращения целого дво­ичного числа со знаком в код ASCII.

  2. Напишите подпрограмму на языке ассемблера для превращения инфикс­ной формулы в обратную польскую запись.

  3. «Ханойская башня» — это не единственная рекурсивная процедура, любимая многими компьютерщиками. Есть еще одна очень популярная рекурсивная процедура п!, где n!=n(n-l)! Подчиняется ограничивающему условию 01=1. Напишите на вашем любимом языке ассемблера процедуру для вычисления п!.

  4. Попробуйте решить задачу «Ханойская башня» без использования рекур­сии путем содержания стека в массиве. Предупреждаем, что, вероятно, вы не сможете найти решения.