Wenn ich C-Code mit meiner Cross-Toolchain kompiliere, druckt der Linker Seiten mit Warnungen, die besagen, dass meine ausführbare Datei Hard Floats verwendet, meine Libc jedoch Soft Floats. Was ist der Unterschied?
Wenn ich C-Code mit meiner Cross-Toolchain kompiliere, druckt der Linker Seiten mit Warnungen, die besagen, dass meine ausführbare Datei Hard Floats verwendet, meine Libc jedoch Soft Floats. Was ist der Unterschied?
Antworten:
Harte Schwimmer verwenden eine On-Chip-Gleitkommaeinheit. Soft Floats emulieren einen in Software. Der Unterschied ist die Geschwindigkeit. Es ist seltsam zu sehen, dass beide auf derselben Zielarchitektur verwendet werden, da der Chip entweder eine FPU hat oder nicht. Sie können Soft-Floating Point in GCC mit -msoft-float aktivieren. Möglicherweise möchten Sie Ihre libc neu kompilieren, um Hardware-Gleitkomma zu verwenden, wenn Sie es verwenden.
Es gibt drei Möglichkeiten, Gleitkomma-Arithmetik durchzuführen:
Genau genommen scheinen mir all diese Antworten falsch zu sein.
Wenn ich C-Code mit meiner Cross-Toolchain kompiliere, druckt der Linker Seiten mit Warnungen, die besagen, dass meine ausführbare Datei Hard Floats verwendet, meine Libc jedoch Soft Floats. Was ist der Unterschied?
Das Debian VFP-Wiki enthält Informationen zu den drei Auswahlmöglichkeiten für -mfloat-abi
:
soft
- Das ist reine Softwaresoftfp
- Dies unterstützt eine Hardware-FPU, aber der ABI ist soft-kompatibel.hard
- Der ABI verwendet Float- oder VFP- Register.Der Linker (Loader) -Fehler liegt daran, dass Sie über eine gemeinsam genutzte Bibliothek verfügen, die Gleitkommawerte in Ganzzahlregistern übergibt. Sie können immer noch Ihren Code mit einem kompilieren -mfpu=vfp
, etc , aber Sie sollten verwenden , -mfloat-abi=softfp
so dass , wenn die libc einen Schwimmer muss es in einer Weise geleitet wird , die Bibliothek versteht.
Der Linux-Kernel kann die Emulation der VFP-Anweisungen unterstützen. Offensichtlich ist es -mfpu=none
für diesen Fall besser, mit zu kompilieren, und die Kompilierung lässt Code direkt generieren, anstatt sich auf eine Linux-Kernel-Emulation zu verlassen. Ich glaube jedoch nicht, dass der Fehler des OP tatsächlich mit diesem Problem zusammenhängt. Es ist getrennt und muss auch zusammen mit dem behandelt werden -mfloat-abi
.
Die gemeinsam genutzte Armv5-Bibliothek mit ArmV7-CPU ist das Gegenteil von dieser. Die libc war hart schwebend, aber die Anwendung war nur weich . Es gibt einige Möglichkeiten, um das Problem zu umgehen, aber das Neukompilieren mit den richtigen Optionen ist immer am einfachsten.
Ein weiteres Problem besteht darin, dass der Linux-Kernel VFP-Tasks (oder einen beliebigen vorhandenen ARM-Gleitkomma) unterstützen muss, um die Register auf einem Kontextwechsel zu speichern / wiederherzustellen.
Es hört sich so an, als ob Ihre libc für Software-Gleitkommaoperationen erstellt wurde, während Ihre exe unter der Annahme der Hardwareunterstützung für Gleitkomma kompiliert wurde. Kurzfristig könnten Sie Soft Floats als Compiler-Flag erzwingen. (Wenn Sie gcc verwenden, denke ich, ist es -msoft-float)
Längerfristig, wenn der Prozessor Ihres Ziels Hardware-Unterstützung für Gleitkommaoperationen bietet, möchten Sie im Allgemeinen eine Cross-Toolchain mit aktiviertem Hardware-Float erstellen oder finden, um die Geschwindigkeit zu erhöhen. Einige Prozessorfamilien haben Modellvarianten, einige mit und einige ohne Hardwareunterstützung. Wenn Sie beispielsweise nur sagen, dass Ihr Prozessor ein ARM ist, reicht es nicht aus, zu wissen, ob Sie Hardware-Gleitkomma-Unterstützung haben.
Die Berechnung kann entweder durch Gleitkomma-Hardware oder in Software erfolgen, die auf ganzzahliger Arithmetik basiert.
Dies in Hardware zu tun ist viel schneller, aber viele Mikrocontroller haben keine Gleitkomma-Hardware. In diesem Fall können Sie entweder die Verwendung von Gleitkommazahlen vermeiden (normalerweise die beste Option) oder sich auf eine Implementierung in Software verlassen, die Teil der C-Bibliothek ist.
In einigen Controller-Familien, z. B. ARM, ist die Gleitkomma-Hardware in einigen Modellen der Familie vorhanden, in anderen jedoch nicht. Daher unterstützt gcc für diese Familien beide. Ihr Problem scheint zu sein, dass Sie die beiden Optionen verwechselt haben.