В чем разница между жесткими и мягкими числами с плавающей запятой? - PullRequest
92 голосов
/ 23 июля 2010

Когда я компилирую код C с помощью моей перекрестной цепочки инструментов, компоновщик печатает страницы с предупреждениями о том, что мой исполняемый файл использует жесткие числа, а мой libc использует мягкие числа.Какая разница?

Ответы [ 5 ]

93 голосов
/ 23 июля 2010

Твердые числа с плавающей запятой используют встроенный модуль с плавающей запятой.Мягкие поплавки подражают одному в программном обеспечении.Разница в скорости.Странно видеть, что оба используются на одной целевой архитектуре, поскольку чип либо имеет FPU, либо его нет.Вы можете включить мягкую плавающую точку в GCC с помощью -msoft-float.Вы можете перекомпилировать ваш libc для использования аппаратного с плавающей запятой, если вы его используете.

30 голосов
/ 23 июля 2010

Существует три способа выполнения арифметики с плавающей запятой:

  • Используйте инструкции с плавающей запятой, если у вашего процессора есть FPU.(быстро)
  • Пусть ваш компилятор переведет арифметику с плавающей запятой в целочисленную арифметику.(медленно)
  • Используйте инструкции с плавающей точкой и процессор без FPU.Ваш ЦП будет генерировать исключение (Reserved Instruction, Unimplemented Instruction или подобное), и если ядро ​​вашей ОС включает эмулятор с плавающей запятой, то он будет эмулировать эти инструкции (самые медленные).
20 голосов
/ 17 апреля 2015

Строго говоря, все эти ответы кажутся мне неправильными.

Когда я компилирую код C с помощью моей перекрестной цепочки инструментов, компоновщик печатает страницы с предупреждениями о том, что мой исполняемый файл использует жесткие числа, а мой libc использует мягкие числа. Какая разница?

Debian VFP wiki содержит информацию о трех вариантах выбора -mfloat-abi,

  • soft - это чистое программное обеспечение
  • softfp - это поддерживает аппаратный FPU, но ABI программно совместим.
  • hard - ABI использует float или VFP регистров.

Ошибка компоновщика (загрузчика) из-за того, что у вас есть общая библиотека, которая будет передавать значения с плавающей запятой в целочисленных регистрах. Вы по-прежнему можете скомпилировать свой код с помощью -mfpu=vfp и т. Д., Но вы должны использовать -mfloat-abi=softfp, чтобы, если libc нужен float, он передавался так, как понимает библиотека.

Ядро Linux может поддерживать эмуляцию инструкций VFP. Очевидно, что для этого лучше компилировать с -mfpu=none, и компиляция должна генерировать код напрямую, а не полагаться на эмуляцию ядра Linux. Однако я не верю, что ошибка ОП на самом деле связана с этой проблемой. Он является отдельным и должен также рассматриваться вместе с -mfloat-abi.

Общая библиотека Armv5 с процессором ArmV7 противоположна этой; libc был жестким, но приложение было только soft . У него есть несколько способов обойти эту проблему, но перекомпиляция с правильными параметрами всегда проще всего.

Другая проблема заключается в том, что ядро ​​Linux должно поддерживать задачи VFP (или любую другую с плавающей точкой ARM) для сохранения / восстановления регистров при переключении контекста.

12 голосов
/ 23 июля 2010

Похоже, ваш libc был создан для программных операций с плавающей запятой, в то время как ваш exe был скомпилирован с учетом аппаратной поддержки с плавающей запятой.В краткосрочной перспективе вы можете использовать мягкое плавание как флаг компилятора.(если вы используете gcc, я думаю, что это -msoft-float)

В долгосрочной перспективе, если процессор вашей цели имеет аппаратную поддержку для операций с плавающей запятой, вы обычно захотите собрать или найти перекрестную цепочку инструментов с аппаратным плавающимвключен для скорости.Некоторые семейства процессоров имеют варианты моделей, некоторые с аппаратной поддержкой, а некоторые без поддержки оборудования.Так, например, просто сказать, что ваш процессор является ARM, недостаточно, чтобы узнать, есть ли у вас аппаратная поддержка с плавающей запятой.

7 голосов
/ 23 июля 2010

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

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

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

...