IEEE с плавающей запятой против пользовательской производительности с плавающей запятой

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

Как выглядит производительность, скажем, умножение для этих трех типов:
1. Поплавок IEEE (32)
2. Пользовательский 32-битный класс с плавающей запятой с 16-битным значением со знаком и 16-битным показателем со знаком.
3. 32-разрядный фиксированный десятичный

Я хочу что-то, что будет масштабироваться до процессора с модулем с плавающей запятой, будет ли пользовательский с плавающей точкой конкурентоспособным по производительности с IEEE? Я слышал, что производительность операций с плавающей запятой IEEE ужасна на процессорах без FPU. Это потому, что он должен работать безумно и / или из-за того, что 24-битное значение не является нативным? То есть, уменьшит ли пользовательский класс с плавающей точкой эту проблему производительности?

Любая помощь будет принята с благодарностью!

7

Решение

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

  • +/ -инфинити на входе
  • Не-номер на входе
  • +/ -0 на входе
  • нормализованное или денормализованное число на входе и неявное «1» в мантиссе
  • распаковка и упаковка
  • Нормализация / денормализация
  • проверка недо- и переполнения
  • правильное округление, которое может привести к дополнительной (де) нормализации и / или переполнению / переполнению

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

Поэтому, если вам интересна арифметика с плавающей точкой, соответствующая IEEE, ожидайте, что каждая эмулируемая операция будет примерно в 30 раз медленнее, чем ее целочисленный аналог (комментарий CodesInChaos является своевременным с 38 тактами на сложение / умножение).

Вы можете обрезать некоторые углы, выбрав формат с плавающей запятой с помощью:

  • только один ноль
  • нет не-номер
  • только нормализованные числа
  • нет неявного «1» в мантиссе
  • экспонента и мантисса, каждая из которых занимает целое число байтов
  • нет или примитивное округление
  • возможно, бесконечности нет
  • возможно, 2-е дополнение мантиссы
  • возможно, нет смещения экспоненты

Арифметика с фиксированной точкой может оказаться намного более производительной. Но обычная проблема заключается в том, что вам нужно заранее знать все диапазоны входных и промежуточных результатов, чтобы вы могли выбрать правильный формат, чтобы избежать переполнения. Вам также, вероятно, потребуется ряд различных поддерживаемых форматов с фиксированной запятой, например, 16,16, 32,32, 8,24, 0,32. Шаблоны C ++ могут помочь уменьшить дублирование кода.

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

РЕДАКТИРОВАТЬ: Для примера более простого формата с плавающей точкой, взгляните на 32-разрядный формат MIL-STD-1750A с плавающей запятой:

 MSB                                         LSB MSB          LSB
------------------------------------------------------------------
| S|                   Mantissa                 |    Exponent    |
------------------------------------------------------------------
0  1                                        23 24            31

Числа с плавающей запятой представлены в виде дробной мантиссы, умноженной на 2, возведенной в степень экспоненты. Все числа с плавающей запятой предполагаются нормализованными или равными нулю с плавающей запятой в начале операции с плавающей запятой, а результаты всех операций с плавающей запятой нормализуются (нормализованное число с плавающей запятой имеет знак мантиссы и следующего бита противоположного значения) или ноль с плавающей точкой Ноль с плавающей точкой определяется как 0000 000016, то есть нулевая мантисса и нулевая экспонента (0016). Расширенный ноль с плавающей точкой определяется как 0000 0000 000016, то есть нулевая мантисса и нулевой показатель степени. Некоторые примеры машинного представления для 32-битных чисел с плавающей точкой:

Десятичное число Шестнадцатеричная запись
(Мантисса х Эксп)
0,999998 х 2127     7FFFFF 7F
0,5 х 2127   400000 7F
0,625 х 24   500000 04
0,5 х 21     400000 01
0,5 х 20     400000 00
0,5 х 2-1    400000 франков
0,5 х 2-128  400000 80
0,0 х 20     000000 00
-1,0 х 20    800000 00
-0,5000001 х 2-128   BFFFFF 80
-0,7500001 х 24  9FFFFF 04
9

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]