Опубликован: 18.05.2006 | Уровень: для всех | Доступ: платный | ВУЗ: Ульяновский государственный университет
Лекция 8:

Сопроцессоры

< Лекция 7 || Лекция 8: 123 || Лекция 9 >

Математические сопроцессоры фирмы Intel

Современные процессоры архитектуры IA-32 содержат блок операций с вещественными числами (Floating Point Unit - FPU). Функционирование этого блока во многом основано на архитектуре первого представителя семейства математических сопроцессоров Intel - 8087.

Сопроцессор 8087 был разработан в 1980 г. Структура сопроцессора 8087 показана на рис. 8.1. В схеме сопроцессора 8087 можно выделить две подсистемы: устройство шинного интерфейса и устройство с плавающей точкой. Развитием этого семейства стал сопроцессор 80287, созданный в 1985 году. Основные изменения произошли только в устройстве шинного интерфейса. В отличие от 8087, сопроцессор 80287 не имеет доступа к шине адреса, поэтому все обращения к памяти выполняет ЦП. В сопроцессоре 80387 изменения коснулись устройства с плавающей точкой: изменилась схема обработки ошибок, а также был реализован больший набор трансцендентных функций.

Структура сопроцессора 8087

Рис. 8.1. Структура сопроцессора 8087

Выпуск очередного поколения ЦП фирмы Intel ознаменовался внедрением блока вещественной арифметики в структуру ЦП. Первым таким представителем семейства процессоров стал i486DX.

В пятом поколении процессоров интеграция блока FPU в суперскалярную архитектуру позволила значительно повысить эффективность выполнения операций с вещественными числами. Блок FPU может выполнять одну операцию с плавающей точкой в каждом такте или же получать и одновременно выполнять 2 команды с плавающей точкой, одной из которых должна быть команда обмена. Команды с плавающей точкой проходят по целочисленному конвейеру (обычно только по U-конвейеру - 5 ступеней) и передаются на исполнительные ступени конвейера FPU (3 ступени). В целом же, несмотря на то, что блок FPU интегрирован в центральный процессор, этот блок работает независимо и одновременно с устройством целочисленных вычислений.

Дальнейшее развитие этого семейства сопровождалось дополнением набора команд блока FPU специальными функциональными подмножествами: MMX, SSE, SSE2.

В целом базовая программная модель всех перечисленных сопроцессоров и блока FPU у IA-32 сходная (рис. 8.2): регистровый стек (восемь 80-битных регистров R0-R7), слово тегов, регистр управления, регистр состояния, указатель команды и указатель данных.

Программная модель сопроцессоров семейства Intel х87

Рис. 8.2. Программная модель сопроцессоров семейства Intel х87

Для хранения данных в сопроцессоре предназначены регистры R0-R7. Эти регистры организованы в стек, и доступ к ним производится относительно вершины стека - ST. Номер регистра, соответствующего вершине стека, хранится в регистре состояния (поле TOS). Как и у ЦП, стек сопроцессора растет к регистрам с меньшими адресами. Команды, которые производят запоминание и извлечение из стека, передают данные из текущего регистра ST, а затем производят инкремент поля TOS в регистре состояния. Многие команды сопроцессора допускают неявное обращение к вершине стека, обозначаемой ST или ST(0). Для указания i-го регистра относительно вершины используется обозначение ST(i), где I = 0,:,7. Например, если поле TOS регистра состояния содержит значение 0112 (вершиной стека является регистр R3), то команда FADD ST,ST(2) суммирует содержимое регистров R3 и R5. Стековая организация упрощает программирование подпрограмм, допуская передачу параметров в регистровом стеке сопроцессора.

Старший байт регистра состояния содержит:

  • Бит занятости B (бит 15), сигнализирующий, свободен ли сопроцессор (B=0) или занят выполнением численной команды (B = 1). Команды сопроцессора, которые используют регистровый стек, требуют, чтобы перед началом их выполнения сопроцессор не был занят. В FPU этот бит дублирует значение флага сигнализации особого случая.
  • Поле TOS "Top-Of-the-Stack" (биты 11-13), которое содержит номер регистра, являющегося логической вершиной стека. При помещении в регистровый стек нового числа это значение уменьшается. Если это поле достигает значения 0, возможны две ситуации: произойдет заворачивание стека на регистры с большими номерами (т.е. R7) или, если заворачивание приведет к затиранию несохраненного значения, возникнет особый случай сопроцессора "переполнение стека".
  • 4 бита кода условия (биты 14, 10, 9, 8), аналогичные флажкам состояния FLAGS у IA-32, отражающие результат арифметических операций. Эти флажки могут быть использованы для условных переходов.

Младший байт регистра состояния содержит флажки особых случаев сопроцессора: переполнение стека, потеря точности, потеря значащих разрядов, численное переполнение, деление на ноль, денормализация, недействительная операция. Если соответствующий особый случай возник и не был замаскирован (в слове управления), это приведет к генерации центральным процессором особого случая сопроцессора (#16).

Младшее слово регистра управления содержит биты масок особых случаев. Сопроцессор допускает индивидуальное маскирование особых случаев. Если тот или иной особый случай замаскирован, при возникновении соответствующей ситуации сопроцессор выполняет некоторые заранее определенные внутренние действия, которые зачастую приемлемы для большинства применений. Например, если замаскирован особый случай деления на ноль, то выполнение операции 85,32/0 даст результат + \infty.

Старшее слово регистра управления содержит два поля: управление точностью PC (биты 8 и 9) и управление округлением RC (биты 10 и 11). Биты управления точностью можно использовать для понижения точности вычислений. По умолчанию используется расширенная точность (PC = 112), можно также использовать двойную точность (PC = 102) и одинарную точность (PC = 002) по стандарту IEEE-754.

Если результат численной операции не может быть точно представлен в выбранном формате, сопроцессор выполняет округление в соответствии с полем RC (табл. 8.3). По умолчанию RC = 00. В примерах в табл. 7.3 сделана попытка представить числа +2,23 и +2,05 в виде двоичных вещественных чисел с 3-битной дробной частью мантиссы. В этом формате нельзя подобрать точное двоичное значение для этих чисел. Ближайшие к ним представимые числа - +2,00 (+1,000E21) и +2,25 (+1,001E21).

Таблица 8.3. Режимы округления сопроцессоров Intel x87
RC Режим

Пример 1

1,000E21 < 2,23E100 < 1,001E21
-1,001E21 < -2,23E100 < -1,000E21

Пример 2

1,000E21 < 2,05E100 < 1,001E21
-1,001E21 < -2,05E100 < -1,000E21
00 Округление к ближайшему (или четному)
2,23E_{10}0 \approx  1,001E_{2}1
-2,23E_{10}0 \approx  -1,001E_{2}1
2,05E_{10}0 \approx  1,000E_{2}1
-2,05E_{10}0 \approx  -1,000E_{2}1
01 Округление вниз (к \infty )
2,23E_{10}0 \approx  1,000E_{2}1
-2,23E_{10}0 \approx  -1,001E_{2}1
2,05E_{10}0 \approx  1,000E_{2}1
-2,05E_{10}0 \approx  -1,001E_{2}1
10 Округление вверх (к + \infty )
2,23E_{10}0 \approx  1,001E_{2}1
-2,23E_{10}0 \approx  -1,000E_{2}1
2,05E_{10}0 \approx  1,001E_{2}1
-2,05E_{10}0 \approx  -1,000E_{2}1
11 Округление к нулю (усечение)
2,23E_{10}0 \approx  1,000E_{2}1
-2,23E_{10}0 \approx  -1,000E_{2}1
2,05E_{10}0 \approx  1,000E_{2}1
-2,05E_{10}0 \approx  -1,000E_{2}1

Регистр тегов содержит 8 тегов - признаков, характеризующих содержимое соответствующего численного регистра сопроцессора. Тег может принимать следующие значения:

00 - в регистре находится действительное число;

01 - нулевое число в регистре;

10 - недействительное число (бесконечность, денормализованное число, нечисло);

11 - пустой регистр.

Сопроцессор использует теги, чтобы определить переполнение или опустошение стека. Если при помещении в стек очередного числа окажется, что декрементированный TOS указывает на непустой регистр (соответствующий тег не равен 112), сопроцессор сигнализирует о переполнении стека. Если при извлечении из стека числа окажется, что инкрементированный TOS указывает на пустой регистр (соответствующий тег равен 112), сопроцессор сигнализирует об опустошении стека.

Указатель команд и указатель данных содержат логические адреса (селектор сегмента и смещение) последней команды и ее операнда. (это 32-битные регистры у 8087 и 80287 и 48-битные - у 80387 и FPU). Эта информация используется обработчиком особых случаев сопроцессора.

Для команд сопроцессора выделена группа кодов, начинающаяся с 11011ххх. В ассемблерах мнемоники команд сопроцессора начинаются с "F": FADD (сложение), FCOM (сравнение), FCOS (косинус), FDIV (деление) и т.п.

Параллельная работа ЦП и сопроцессора ставит перед программистом проблемы синхронизации. Например:

mem   DW    0
      :
     FILD  mem
     INC   mem
     FSQRT

В данном примере, команда FILD преобразует 16-битное целое число в памяти в формат сопроцессора и сохраняет его в ST, затем целочисленная команда INC увеличивает это значение на 1, после чего сопроцессор вычисляет квадратный корень ST (FSQRT).

Для внешних сопроцессоров (8087, 80287, 80387) ЦП начнет выполнять команду INC раньше, чем сопроцессор закончит FILD, а, следовательно, в стек сопроцессора может попасть неверное значение. Встроенный блок FPU у IA-32 лишен этого недостатка, т. к. ЦП отслеживает обращения к памяти и не начнет выполнять целочисленную команду, если она обращается к ячейке памяти, с которой в данный момент работает блок FPU. Однако остается нерешенной другая проблема. Если при выполнении инструкции FPU возникает ситуация, соответствующая одному из незамаскированных особых случаев, FPU прекращает выполнение инструкции и сигнализирует об особом случае. Однако соответствующее исключение процессора будет вызвано только при очередном обращении процессора к блоку FPU, а до этого момента целочисленный блок может изменить ячейку памяти, значение которой привело к исключению, так что обработчик исключения не сможет правильно интерпретировать причину особого случая.

Описанная ситуация говорит о необходимости использовать в таких случаях средства синхронизации. Например, команда FWAIT приостанавливает работу целочисленного устройства до тех пор, пока не будет завершена работа выполняемой сопроцессором инструкции или не будет вызвано исключение, если при выполнении последней инструкции FPU возник особый случай. Для этих же целей можно использовать любую другую инструкцию сопроцессора, кроме специальных "неожидающих" инструкций: FNINIT - сброс сопроцессора без ожидания, FNSTCW/FNSTSW - сохранение регистра управления/состояния без ожидания, FNCLEX - сбросить флаги особых случаев без ожидания, FNSAVE/FNSTENV - сохранение состояния (контекста) сопроцессора без ожидания.

Таким образом, для решения проблемы синхронизации приведенный выше пример следует переписать так:

FILD	mem
FSQRT
INC	mem
< Лекция 7 || Лекция 8: 123 || Лекция 9 >
Виктория Монахова
Виктория Монахова
Евгений Коваленко
Евгений Коваленко
Сергей Бурнышев
Сергей Бурнышев
Россия
Леонид Сустретов
Леонид Сустретов
Россия, Аксайский р-н