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

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

Ответ 1

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

Ответ 2

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

  • Используйте команды float, если ваш CPU имеет FPU. (Быстро)
  • Попросите ваш компилятор преобразовать арифметику с плавающей точкой в ​​целочисленную арифметику. (Медленно)
  • Используйте команды float и CPU без FPU. Ваш процессор будет генерировать исключение (зарезервированная инструкция, невыполненная инструкция или аналогичная), и если ваше ядро ​​ОС включает в себя эмулятор с плавающей запятой, оно будет эмулировать эти инструкции (самые медленные).

Ответ 3

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

Когда я скомпилирую код 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) для сохранения/восстановления регистров в контекстном коммутаторе.

Ответ 4

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

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

Ответ 5

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

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

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