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


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

5 83

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 для этих семей поддерживает оба. Ваша проблема, кажется, что вы перепутали два варианта.