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