Как операции с плавающей запятой эмулируются в программном обеспечении?

Как программное обеспечение выполняет арифметику с плавающей запятой, когда в ЦП нет (или глючит) модуля с плавающей запятой? Примерами могут служить архитектуры микроконтроллеров PIC, AVR и 8051.


person Ahmed Saleh    schedule 01.10.2016    source источник
comment
Эмулировать? Совсем не на процессорах X86/64. Какую арку вы имеете в виду?   -  person deviantfan    schedule 01.10.2016
comment
я говорю о микроконтроллерах PIC, AVR, 8051   -  person Ahmed Saleh    schedule 01.10.2016
comment
Это произошло до того, как вы рассказали нам об арке. И в идеале вы должны включить эту информацию в сам вопрос.   -  person deviantfan    schedule 01.10.2016
comment
@deviantfan: Для всех, кто слышал о hardfloat и softfloat, было совершенно ясно, что он говорит о последнем. Точная архитектура не имеет значения, если вы знаете, к какой из двух категорий она относится. Кроме того, люди ДЕЙСТВИТЕЛЬНО эмулируют операции с плавающей точкой на x86, например, чтобы избежать wiki/Pentium_FDIV_bug" rel="nofollow noreferrer">известная ошибка Pentium с делением с плавающей запятой.   -  person Ben Voigt    schedule 01.10.2016
comment
Другой случай, когда операции с плавающей запятой должны быть реализованы программно, — это когда требуется большая точность, чем поддерживает аппаратный FPU. Некоторые операции криптографии с эллиптическим ключом требуют высокоточных реализаций с плавающей запятой.   -  person Ben Voigt    schedule 01.10.2016
comment
@BenVoigt: ваш пример криптографии не является эмуляцией; также нет какой-либо реализации FP на PIC, AVR или 8051; ни один из них не определяет FPU и не имеет инструкций FPU, поэтому нечего эмулировать. Эмуляция используется для архитектур, которые определяют FPU, но для которых FPU может отсутствовать, чтобы обрабатывать двоичные файлы, содержащие инструкции FPU, для целей, не имеющих FPU. Поэтому по определению вы не можете эмулировать FPU на этих архитектурах; Вы можете просто реализовать операции с плавающей запятой. Реализация — это не эмуляция.   -  person Clifford    schedule 02.10.2016
comment
Это относится не только к языку, но и к архитектуре.   -  person too honest for this site    schedule 02.10.2016


Ответы (4)


"Эмуляция" — неправильный термин в контексте PIC, AVR и 8051. Эмуляция с плавающей запятой относится к эмуляции аппаратного обеспечения FPU в архитектурах, которые имеют опцию FPU, но для которых не все части включают FPU. Это позволяет запускать двоичный файл, содержащий инструкции с плавающей запятой, на варианте без FPU. Там, где это используется, эмуляция FPU реализуется как обработчик исключений с недопустимыми инструкциями; когда встречается инструкция FPU, но FPU отсутствует, возникает исключение, и обработчик считывает значение инструкции и реализует операцию в программном обеспечении.

Однако ни одна из перечисленных вами архитектур не определяет инструкции FPU или FPU, поэтому эмулировать нечего. Вместо этого в этих случаях операции с плавающей запятой полностью реализуются в программном обеспечении, а компилятор генерирует код для вызова подпрограмм с плавающей запятой по мере необходимости. Например, выражение x = y * z ; сгенерирует код, эквивалентный вызову функции x = _fmul( y, z ) ;. На самом деле, если вы посмотрите на вывод карты компоновщика из сборки, содержащей операции с плавающей запятой, вы, вероятно, увидите обычные имена символов, такие как _fmul, _fdiv и им подобные - эти функции являются внутренними для компилятора.

person Clifford    schedule 01.10.2016
comment
На уровне машинного кода вы правы; в этой архитектуре нет инструкций с плавающей запятой, которые можно было бы эмулировать. Но этот вопрос касается С++, а не ассемблера, и С++ в некоторых случаях действительно предоставляет встроенные операции с плавающей запятой. Имитируется именно эта встроенная природа. Небольшое примечание об эмуляции инструкций: обработчик недопустимых инструкций является наиболее простым подходом, но возможны и другие подходы, такие как своевременная бинарный перевод. - person Ben Voigt; 02.10.2016
comment
@BenVoigt: в вопросе не упоминается конкретный язык, меньше всего C ++, и хотя я использовал C ++ на AVR, он обычно не используется и не широко доступен на PIC и 8051. Я бы не назвал это эмуляцией в любом случае. Есть много операторов, которые нельзя напрямую преобразовать в одну инструкцию; на 8-битной цели, которая верна для 16- и 32-битных целочисленных операций - вы бы не назвали их реализацию эмуляцией. Реализация оператора несколькими инструкциями или вызовом подпрограммы не является эмуляцией. Это просто неправильный термин, как ни посмотри. - person Clifford; 03.10.2016
comment
С++ определенно упоминался, пока Олаф не удалил его. - person Ben Voigt; 03.10.2016
comment
@BenVoigt: Достаточно справедливо, но я предлагаю удалить его, потому что это было актуально. Использование C++ не меняет смысла эмуляции. - person Clifford; 03.10.2016

Плавающая точка - это просто научная запись в базе 2. И мантисса, и экспонента являются целыми числами, и библиотеки softfloat разбивают операции с плавающей частью на операции, влияющие на мантиссу и экспоненту, которые могут использовать поддержку целых чисел ЦП.

Например, (x 2n) * (y 2m) = x * y 2n+m.

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

person Ben Voigt    schedule 01.10.2016
comment
Благодарю. какой смысл использовать математику с фиксированной запятой и преобразовывать математику с плавающей запятой в математику с фиксированной запятой, а у микроконтроллера нет FPU. - person Ahmed Saleh; 02.10.2016
comment
@AhmedSaleh: Этот ответ, без сомнения, является ответом на вопрос, который, как вы думали, вы задали, и объясняет (вкратце), как операции FP могут быть реализованы в программном обеспечении, но это не эмуляция; указанные цели не могут поддерживать эмуляцию, поскольку у них нет инструкций FP для эмуляции. - person Clifford; 02.10.2016
comment
@AhmedSaleh: Ваши вопросы, касающиеся операций с плавающей запятой и фиксированной запятой, заслуживают публикации другого вопроса (хотя, вероятно, такие вопросы уже есть на SO) - короче говоря, реализация операций с фиксированной запятой на целочисленном процессоре требует меньше инструкций и быстрее и более детерминирован, чем программно реализованные числа с плавающей запятой. С другой стороны, числа с плавающей запятой поддерживают более широкий диапазон значений с меньшим количеством битов. - person Clifford; 02.10.2016

Плавающая точка не "эмулируется". Обычно они хранятся, как описано в IEEE754.

Фиксированная точка — это другой тип реализации. Число 2,54 может быть реализовано как с фиксированной, так и с плавающей запятой.

Программная реализация VS FPU (модуль с плавающей запятой)

Некоторые современные микроконтроллеры, такие как ARM cortex M4F, имеют блок с плавающей запятой и могут выполнять операции с плавающей запятой (такие как умножение, деление, сложение) на аппаратном уровне намного быстрее, чем программное обеспечение.

В 8-битных микроконтроллерах, таких как AVR, PIC и 8051, операции выполняются только программно (деление может занимать до сотен операций). Ему придется отдельно обрабатывать часть мантиссы (дробной части) и часть экспоненты, а также все особые случаи (например, NaN). У компилятора часто есть много подпрограмм, угрожающих одной и той же операции (например, деление), и он будет выбирать в зависимости от оптимизации (размер/скорость) и других параметров (например, если он знает, что числа всегда положительны...)

person Julien    schedule 01.10.2016
comment
Я использовал программные библиотеки IEEE754. soft-float часто называют эмуляцией схемы сопроцессора с плавающей запятой. - person Ben Voigt; 01.10.2016
comment
@BenVoigt, у вас есть точка зрения того, кто всегда использует FPU, я больше привык к 8-битным микроконтроллерам (для меня HW float - это особый случай). Первоначальный вопрос был не очень ясен, и я ответил, следуя моему пониманию (до вашего редактирования). - person Julien; 01.10.2016
comment
Где указано, что с плавающей запятой требуется реализация IEEE754 или даже формат. Специально для микроконтроллеров часто используются другие форматы. - person too honest for this site; 02.10.2016

Существует еще один вопрос SO, который охватывает требования стандартов C/C++ к числам с плавающей запятой. Так что, строго говоря, float может быть представлен в любой форме, которую предпочитает компилятор. Но на практике, если ваша реализация с плавающей запятой значительно отличается от IEEE754, вы можете ожидать много ошибок, вызванных программами, которые привыкли к IEEE754. И компилятор должен быть дружелюбным к программисту и не должен создавать проблем, используя неуказанные места стандартов. Таким образом, в большинстве случаев числа с плавающей запятой будут представлены так же, как и во всех других архитектурах, включая x86. Арифметика с фиксированной точкой слишком отличается.

В случае AVR и PIC компилятор знает, что fpu недоступен, поэтому он преобразует каждую операцию в набор команд, которые поддерживает ЦП. Он должен будет нормализовать оба операнда до общего показателя степени, затем выполнить операцию над мантиссом, как над целыми числами, а затем настроить показатель степени. Это довольно много операций, поэтому эмулируемая плавающая точка работает медленно. И, кроме того, если вы оптимизируете размер, каждая операция с плавающей запятой может стать вызовом функции.

А на арке ARM все может быть довольно странно. Есть ARM с FPU и без. И вы можете захотеть иметь универсальное приложение, которое будет работать на обоих. На этот случай есть хитрая (и медленная) схема. Приложение использует команды FPU. Если ваш процессор не имеет FPU, то такая команда вызовет прерывание, и в нем ОС будет эмулировать инструкцию, сбрасывать бит ошибки и возвращать управление приложению. Но эта схема оказалась очень медленной и обычно не используется.

person Alexey Guseynov    schedule 01.10.2016
comment
Для сложения и вычитания требуется общий показатель степени, но не для всех операций. - person Ben Voigt; 01.10.2016