В чем разница между жесткими и мягкими числами с плавающей запятой?
когда я компилирую код C с помощью моей перекрестной цепочки инструментов, компоновщик печатает страницы предупреждений о том, что мой исполняемый файл использует жесткие поплавки, но мой libc использует мягкие поплавки. Какая разница?
5 ответов:
жесткие поплавки использовать встроенный блок вычислений с плавающей запятой. Мягкие поплавки эмулируют один в программном обеспечении. Разница в скорости. Странно видеть, что оба используются на одной и той же целевой архитектуре, так как Чип либо имеет FPU, либо нет. вы можете включить мягкую плавающую точку в GCC с помощью-msoft-float. Вы можете перекомпилировать свой libc для использования аппаратной плавающей точки, если вы ее используете.
существует три способа сделать арифметику с плавающей точкой:
- используйте инструкции float, если ваш процессор имеет FPU. (быстро)
- пусть ваш компилятор переведет арифметику с плавающей запятой в целочисленную арифметику. (медленно)
- используйте инструкции float и процессор без FPU. Ваш процессор будет генерировать исключение (зарезервированная инструкция, нереализованная инструкция или аналогичная), и если ваше ядро ОС включает эмулятор с плавающей запятой, он будет эмулировать эти инструкции (самый медленный.)
строго говоря, все эти ответы мне кажутся неверными.
когда я компилирую код C с помощью моей кросс-инструментальной цепочки, компоновщик печатает страницы предупреждений о том, что мой исполняемый файл использует жесткие поплавки, но мой libc использует мягкие поплавки. Какая разница?
Debian VFP wiki имеет информацию о трех вариантах для
-mfloat-abi
,
soft
- это чистое программное обеспечениеsoftfp
- это поддерживает аппаратный FPU, но ABI мягкий совместимы.hard
- ABI использует float или VFP регистры.ошибка компоновщика (загрузчика) заключается в том, что у вас есть общая библиотека, которая будет передавать значения с плавающей запятой в целочисленных регистрах. Вы все еще можете скомпилировать свой код с помощью
-mfpu=vfp
и т. д. Но вы должны использовать-mfloat-abi=softfp
так что если libc нужен поплавок он передается таким образом библиотека поймет.ядро Linux может поддерживать эмуляцию инструкций VFP. Очевидно, что вам лучше скомпилировать с
-mfpu=none
на этот случай и есть компиляции генерировать код непосредственно вместо того, чтобы полагаться на какой-либо эмуляции ядра Linux. Однако я не считаю, что ошибка OP на самом деле связана с этой проблемой. Он является отдельным и также должен рассматриваться вместе с-mfloat-abi
.Общая библиотека Armv5 с процессором ArmV7 является противоположностью этого одно;libc было трудно плавать, но приложение было только софт. У него есть несколько способов обойти эту проблему, но перекомпиляция с правильными параметрами всегда самая простая.
другая проблема заключается в том, что ядро Linux должно поддерживать задачи VFP (или любую другую плавающую точку ARM) для сохранения/восстановления регистров на переключателе контекста.
похоже, что ваш libc был построен для программных операций с плавающей запятой, в то время как ваш exe был скомпилирован, предполагая аппаратную поддержку с плавающей запятой. В краткосрочной перспективе вы можете принудительно использовать мягкие поплавки в качестве флага компилятора. (если вы используете gcc, я думаю ,что это-msoft-float)
в долгосрочной перспективе, если процессор вашей цели имеет аппаратную поддержку операций с плавающей запятой, вы, как правило, хотите построить или найти перекрестную цепочку инструментов с аппаратным поплавком, включенным для скорости. Некоторые процессоры семьи имеют варианты модели некоторые С и некоторые без аппаратной поддержки. Так, например, просто сказать, что ваш процессор-это рука, недостаточно, чтобы знать, есть ли у вас аппаратная поддержка с плавающей запятой.
вычисление может быть выполнено либо аппаратным обеспечением с плавающей запятой, либо программным обеспечением на основе целочисленной арифметики.
делать это в аппаратных средствах намного быстрее, но многие микроконтроллеры не имеют аппаратных средств с плавающей запятой. В этом случае вы можете либо избегать использования плавающей точки (обычно это лучший вариант), либо полагаться на реализацию в программном обеспечении, которое будет частью библиотеки C.
в некоторых семействах контроллеров, например ARM, присутствует оборудование с плавающей запятой в некоторых моделях семьи, но не в других, поэтому gcc для этих семей поддерживает оба. Ваша проблема, кажется, что вы перепутали два варианта.