Математический сопроцессор

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Сопроцессор Motorola 68881

Математический сопроцессор — сопроцессор для расширения командного множества центрального процессора и обеспечивающий его функциональностью модуля операций с плавающей запятой, для процессоров, не имеющих интегрированного модуля.

Модуль операций с плавающей запятой (или с плавающей точкой; англ. floating point unit (FPU)) — часть процессора для выполнения широкого спектра математических операций над вещественными числами.

Простым «целочисленным» процессорам для работы с вещественными числами и математическими операциями требуются соответствующие процедуры поддержки и время для их выполнения. Модуль операций с плавающей запятой поддерживает работу с ними на уровне примитивов — загрузка, выгрузка вещественного числа (в/из специализированных регистров) или математическая операция над ними выполняется одной командой, за счёт этого достигается значительное ускорение таких операций.

Сопроцессоры[править | править код]

Основная статья: X87

x87 — это специальный набор инструкций для работы с математическими вычислениями, являющийся подмножеством архитектуры процессоров x86. Такое название он получил, потому что первоначальные отдельные математические сопроцессорные чипы имели названия, заканчивающиеся на 87. Как и другие расширения базового набора инструкций процессора, эти инструкции не являются строго необходимыми для построения рабочей программы, но будучи аппаратно реализованными, общие математические задачи они позволяют выполнять гораздо быстрее. Например, в наборе инструкций x87 присутствуют команды для расчёта значений синуса или косинуса.

Сопроцессоры Intel семейства x86[править | править код]

Для процессоров семейства x86 с 8086/8088 по 386 модуль операций с плавающей запятой был выделен в отдельную микросхему, называемую математическим сопроцессором. Для установки сопроцессора на плате компьютера предусматривался отдельный разъём.

Сопроцессор не является полноценным процессором, так как не умеет делать многих необходимых для этого операций (например, не умеет работать с программой и вычислять адреса памяти), являясь всего лишь придатком центрального процессора.

Одна из схем взаимодействия центрального процессора и сопроцессора, применяемая, в частности, в x86-сопроцессорах, реализуется следующим образом:

  • Сопроцессор подключен к шинам центрального процессора, а также имеет несколько специальных сигналов для синхронизации процессоров между собой.
  • Часть командных кодов центрального процессора зарезервирована для сопроцессора, он следит за потоком команд, игнорируя другие команды. Центральный процессор, наоборот, игнорирует команды сопроцессора, занимаясь только вычислением адреса в памяти, если команда предполагает к ней обращение. Центральный процессор делает цикл фиктивного считывания, позволяя сопроцессору считать адрес с адресной шины. Если сопроцессору необходимо дополнительное обращение к памяти (для чтения или записи результатов), он выполняет его через захват шины.
  • После получения команды и необходимых данных сопроцессор начинает её выполнение. Пока сопроцессор выполняет команду, центральный процессор выполняет программу дальше, параллельно с вычислениями сопроцессора. Если следующая команда также является командой сопроцессора, процессор останавливается и ожидает завершения выполнения сопроцессором предыдущей команды.
  • Также существует специальная команда ожидания (FWAIT), принудительно останавливающая процессор до завершения вычислений (если для продолжения программы необходимы их результаты). В настоящее время команда используется лишь для обработки исключений при работе с плавающей точкой, работа процессора и сопроцессора синхронизируется автоматически[1].

Начиная с процессора Intel486DX модуль операций с плавающей запятой был интегрирован в центральный процессор и назван FPU. В линейке Intel486SX модуль FPU отключался (поначалу в эту линейку попадали процессоры с бракованным FPU). Для процессоров Intel486SX также выпускался «сопроцессор» Intel487SX, но фактически он являлся процессором Intel486DX, и при его установке процессор Intel486SX отключался.

Несмотря на интеграцию, FPU в процессорах i486 представляет собой неизменный сопроцессор, выполненный на том же кристалле, более того, схема FPU i486 полностью идентична сопроцессору предыдущего поколения 387DX вплоть до тактовой частоты (в два раза меньшей, чем частота центрального процессора). Настоящая интеграция FPU c центральным процессором началась только в процессорах Pentium модели MMX.

Сопроцессоры x86 от сторонних производителей[править | править код]

Широкое распространение в соответствующий период получили сопроцессоры для платформы x86, выпускавшиеся компанией Weitek — ею были выпущены 1167, 2167 в виде набора микросхем и микросхемы 3167, 4167, для процессоров 8086, 80286, 80386, 80486, соответственно. По сравнению с сопроцессорами от Intel они обеспечивали в 2—3 раза большую производительность, но обладали несовместимым программным интерфейсом, реализованным через технологию memory-mapping. Она сводилась к тому, что основной процессор должен был записывать информацию в те или иные области памяти, контролируемые Weitek-овским сопроцессором (собственной оперативной памяти там не было). Конкретный адрес, куда производилась запись, интерпретировался в качестве той или иной команды. Несмотря на несовместимость, сопроцессоры от Weitek были широко поддержаны как разработчиками ПО, так и производителями материнских плат, предусматривавших на них гнёзда для установки такой микросхемы.

Ряд других компаний также выпускал различные несовместимые математические сопроцессоры, реализуя интерфейс к ним через порты ввода-вывода или прерывания BIOS, но они не получили такого широкого распространения.

Компании-производители клонов выпускали совместимые с 80287 80387 сопроцессоры, работавшие быстрее аналогичных интеловских. Среди этих компаний можно упомянуть Cyrix, AMD, Chips & Technologies (C&T). Иногда система команд этих сопроцессоров расширялась несколькими несовместимыми, например, аналог 80287 от C&T содержал команды для работы с вектором из четырёх значений с плавающей точкой. Серьёзной поддержки от производителей ПО эти расширенные команды не получили.

Процессоры EMC87 от фирмы Cyrix могли работать как в режиме программной совместимости с Intel 80387, так и в собственном несовместимом режиме программирования. Для них обеспечивалась аппаратная совместимость с разъёмом 80387-го сопроцессора.

В СССР выпускалась микросхема (КМ)1810ВМ87, которая являлась аналогом 8087.

Другие платформы[править | править код]

Аналогично, материнские платы ПК, построенных на процессорах Motorola, до разработки этой фирмой процессора MC68040 (в который сопроцессор был встроен) содержали математический сопроцессор. Как правило, в качестве FPU использовался сопроцессор 68881 16 МГц или 68882 25 МГц. Практически любой современный процессор имеет встроенный сопроцессор.

Компания Weitek также выпускала математические сопроцессоры для платформ 68000 и MIPS.

Устройство FPU[править | править код]

Регистры FPU организованы не в виде массива, как в некоторых других архитектурах, а как регистровый стек. Таким образом, FPU представляет собой стековый калькулятор, работающий по принципу обратной польской записи[2][3]. Это означает, что команды всегда используют верхнее значение в стеке для проведения операций, а доступ к другим хранящимся значениям обычно обеспечивается в результате манипуляций со стеком. Однако при работе с вершиной стека одновременно могут использоваться и другие элементы стека, для доступа к которым применяется прямая адресация относительно вершины стека. Также в операциях могут использоваться значения, хранящиеся в оперативной памяти. Обычная последовательность действий выглядит следующим образом. Перед операцией аргументы помещаются в LIFO-стек; при выполнении операции необходимое количество аргументов снимается со стека. Результат операции помещается в стек, где может быть использован в дальнейших вычислениях или снят со стека для записи в память. Хотя стековая организация регистров FPU получается и удобной для программистов, она усложняет задачу построения эффективного кода компиляторами.

Особенности использования[править | править код]

Все процессоры Intel и AMD, начиная с 486DX, имеют встроенный математический сопроцессор, и в отдельном сопроцессоре не нуждаются (за исключением Intel486SX). Тем не менее, термин x87 всё ещё применяется для выделения той части инструкций процессора, которая служит для работы с вещественными числами в стеке FPU. Отличительный признак этих инструкций: их мнемоники начинаются с буквы f (от англ. float). Компиляторы могут использовать эти инструкции для производства кода, который в ряде случаев работает быстрее, нежели тот, что использует вызовы к библиотекам для выполнения операций с плавающей запятой.

Инструкции x87 совместимы со стандартом IEEE-754. Однако x87 выполняют операции не в строгом соответствии с форматами IEEE-754 из-за использования более широких регистров по сравнению с форматами чисел одинарной и двойной точности. Поэтому последовательность арифметических операций на наборе x87 может давать несколько иной результат по сравнению с процессором, строго следующим формату IEEE-754.

После появления расширения 3DNow! от AMD и затем SSE, начиная с процессоров Pentium III компании Intel, вычисления с одинарной точностью стало возможным проводить без помощи инструкций FPU, причём с возросшей производительностью. Расширение SSE2 и более поздние расширения системы команд обеспечили также быстрое выполнение расчётов с двойной точностью (см. стандарт IEEE-754). В связи с этим в современных компьютерах потребность в командах классического математического сопроцессора значительно уменьшилась. Тем не менее, во всех выпускаемых x86-процессорах они по-прежнему поддерживаются для совместимости со старыми приложениями, а также для нужд тех приложений, где требуются двоично-десятичные преобразования или вычисления с расширенной точностью (когда двойной точности недостаточно). В настоящее время использование команд x87 остаётся наиболее эффективным способом ведения таких расчётов.

Форматы данных[править | править код]

Внутри FPU числа хранятся в 80-битном формате с плавающей запятой (расширенная точность), для записи же или чтения из памяти могут использоваться:

  • Вещественные числа в трёх форматах: коротком (32 бита), длинном (64 бита) и расширенном (80 бит).
  • Двоичные целые числа в трёх форматах: 16, 32 и 64 бита.
  • Упакованные целые десятичные числа (BCD) числа — длина максимального числа составляет 18 упакованных десятичных цифр (72 бита).

FPU также поддерживает специальные численные значения:

  • Денормализованные вещественные числа — числа, которые по абсолютной величине меньше минимального нормализованного числа. При формировании такого значения в некотором регистре стека в соответствующем этому регистру теге регистра TWR формируется специальное значение 10. Признаком денормализованного числа в его двоичном представлении служит нулевое поле порядка.
  • Бесконечность (положительная и отрицательная), возникает при делении на нуль ненулевого значения, а также при переполнениях. При формировании такого значения в некотором регистре стека в соответствующем этому регистру теге регистра TWR формируется специальное значение 10.
  • нечисло (англ. not-a-number (NaN)). Различают два вида нечисел:
    • SNaN (Signaling Non a Number) — сигнальные нечисла. Сопроцессор реагирует на появление этого числа в регистре стека возбуждением исключения недействительной операции. Сопроцессор не формирует сигнальных чисел. Программисты формируют такие числа преднамеренно, чтобы возбудить в нужной ситуации исключение.
    • QNaN (Quiet Non a Number) — спокойные (тихие) нечисла. Сопроцессор может формировать спокойные нечисла в качестве реакции на определённые исключения, например, число вещественной неопределённости.
  • Нуль (положительный и отрицательный). Хотя с точки зрения формата с плавающей запятой нуль может считаться специальным значением, он в то же время является частным случаем денормализованного числа.
  • Неопределённости и неподдерживаемые форматы. Существует много битовых наборов, которые можно представить в расширенном формате вещественного числа. Для большинства их значений формируется исключение недействительной операции.

Регистры[править | править код]

В FPU можно выделить три группы регистров:

  • Стек процессора: регистры R0..R7. Размерность каждого регистра: 80 бит.
  • Служебные регистры
    • Регистр состояния процессора SWR (Status Word Register) — информация о текущем состоянии сопроцессора. Размерность: 16 бит.
    • Управляющий регистр сопроцессора CWR (Control Word Register) — управление режимами работы сопроцессора. Размерность: 16 бит.
    • Регистр слова тегов TWR (Tags Word Register) — контроль над регистрами R0..R7 (например, для определения возможности записи). Размерность: 16 бит.
  • Регистры указателей
    • Указатель данных DPR (Data Point Register). Размерность: 48 бит.
    • Указатель команд IPR (Instruction Point Register). Размерность: 48 бит.

Система команд сопроцессора[править | править код]

Система включает около 80 команд. Их классификация:

  • Команды передачи данных
    • Вещественные данные
    • Целочисленные данные
    • Десятичные данные
    • Загрузка констант (0, 1, число Пи, log2(10), log2(e), lg(2), ln(2))
    • Обмен
    • Условная пересылка (Pentium II/III)
  • Команды сравнения данных
    • Вещественные данные
    • Целочисленные данные
    • Анализ
    • С нулём
    • Условное сравнение (Pentium II/III)
  • Арифметические команды
    • Вещественные данные: сложение, вычитание, умножение, деление
    • Целочисленные данные: сложение, вычитание, умножение, деление
    • Вспомогательные арифметические команды (квадратный корень, модуль, изменение знака, выделение порядка и мантиссы)
  • Трансцендентные команды
    • Тригонометрия: синус, косинус, тангенс, арктангенс
    • Вычисление логарифмов и степеней
  • Команды управления
    • Инициализация сопроцессора
    • Работа со средой
    • Работа со стеком
    • Переключение режимов

См. также[править | править код]

Примечания[править | править код]

  1. Intel 64 and IA-32 Architectures Software Developer’s Manual. Volume 2A and 2B: Instruction Set Reference. Order numbers #253666, #253667
  2. Intel 64 and IA-32 Architectures Software Developer’s Manual. Volume 1: Basic Architecture. Order number #253665
  3. AMD64 Architecture Programmer’s Manual. Volume 1: Application Programming. Publication number #24592