Was ist der Unterschied zwischen harten und weichen Gleitkommazahlen?

Lesezeit: 5 Minuten

Benutzeravatar von Evan Kroske
Evan Kroske

Wenn ich C-Code mit meiner Cross-Toolchain kompiliere, druckt der Linker Seiten mit Warnungen, die besagen, dass meine ausführbare Datei harte Gleitkommazahlen verwendet, meine libc jedoch weiche Gleitkommazahlen. Was ist der Unterschied?

  • Wenn es sich um eine ARM-Architektur handelt, fügen Sie dies bitte in die Tags ein 🙂

    – Nils Pipenbrinck

    23. Juli 2010 um 19:02 Uhr

  • @Nils Pipenbrinck: MIPS-Chips haben dieses Problem auch

    – Javier

    23. Juli 2010 um 19:04 Uhr

Feste Gleitkommazahlen verwenden eine Gleitkommaeinheit auf dem Chip. Soft Floats emulieren einen in der 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-Gleitkomma in GCC mit -msoft-float aktivieren. Möglicherweise möchten Sie Ihre libc neu kompilieren, um Hardware-Gleitkommazahlen zu verwenden, wenn Sie sie verwenden.

  • „Es ist seltsam zu sehen, dass beide auf derselben Zielarchitektur verwendet werden.“ Dies kann für eine Bibliothek sinnvoll sein, die maschinenunabhängig und bitgenau (Soft Float) in genauigkeitskritischen Teilen und schnell (Hard Float) in Teilen ist, in denen kleine Abweichungen nicht vorhanden sind egal.

    – PhilLab

    29. Mai 2017 um 12:18 Uhr

  • Es passiert auf 32-Bit-ARM.

    – Aaron Franke

    13. Dezember 2018 um 9:49 Uhr

  • Soft Floats können für deterministische Berechnungen verwendet werden, zB für Physiksimulationen. Sie werden jedes Mal, auf jeder Plattform, auf jedem Prozessor die gleichen Ergebnisse liefern.

    – MeatFlavourDev

    25. August 2021 um 3:01 Uhr

Es gibt drei Möglichkeiten, Gleitkommaarithmetik durchzuführen:

  • Verwenden Sie Float-Anweisungen, wenn Ihre CPU über eine FPU verfügt. (schnell)
  • Lassen Sie Ihren Compiler Gleitkomma-Arithmetik in Integer-Arithmetik übersetzen. (langsam)
  • Verwenden Sie Float-Anweisungen und eine CPU ohne FPU. Ihre CPU generiert eine Ausnahme (reservierte Anweisung, nicht implementierte Anweisung oder ähnliches), und wenn Ihr Betriebssystemkern einen Gleitkommaemulator enthält, emuliert er diese Anweisungen (am langsamsten).

Benutzeravatar von artless noise
kunstloser Lärm

Streng genommen scheinen mir alle 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 harte Gleitkommazahlen verwendet, meine libc jedoch weiche Gleitkommazahlen. Was ist der Unterschied?

Das Debian VFP-Wiki hat Informationen zu den drei Möglichkeiten für -mfloat-abi,

  • soft – Dies ist reine Software
  • softfp – Dies unterstützt eine Hardware-FPU, aber die ABI ist softkompatibel.
  • hard – die ABI verwendet schweben oder VFP registriert.

Der Linker- (Loader-) Fehler tritt auf, weil Sie eine gemeinsam genutzte Bibliothek haben, die Gleitkommawerte in Ganzzahlregistern übergibt. Sie können Ihren Code immer noch mit a kompilieren -mfpu=vfpetc, aber Sie sollten verwenden -mfloat-abi=softfp damit, wenn die libc braucht ein Float, es wird so übergeben, wie es die Bibliothek versteht.

Der Linux-Kernel kann die Emulation der VFP-Anweisungen unterstützen. Offensichtlich sind Sie besser dran, mit zu kompilieren -mfpu=none für diesen Fall und lassen Sie die Kompilierung 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 behandelt werden -mfloat-abi.

Die gemeinsam genutzte Armv5-Bibliothek mit der ArmV7-CPU ist das Gegenteil davon. das libc war hart Float, aber die Anwendung war nur Sanft. Es gibt einige Möglichkeiten, 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 was auch immer für ARM-Gleitkommazahlen vorhanden ist) unterstützen muss, um die Register bei einem Kontextwechsel zu speichern/wiederherstellen.

  • Moderne GCC-Versionen (~4.8+) unterstützen ‘multi-lib’, die Hard-Float- und Soft-Float-Bibliotheken haben. Frühere Versionen erforderten einen Compiler, der mit einer bestimmten Version erstellt wurde. Gelegentlich wird der Pfad zur richtigen Bibliothek benötigt, wenn mit einer ‘multi-lib’ gcc-Distribution gelinkt wird, da es mehrere Versionen der Bibliotheken gibt (was eine längere Zeit zum Erstellen des Compilers erfordert). Verzeichnisnamen können ‘hf’, ‘hardf’, ‘libhf’ oder ‘hard-float’ sein, aber sie befinden sich normalerweise unter dem regulären ‘soft’-Verzeichnis oder einem nahe gelegenen Ort.

    – ungekünstelter Lärm

    11. März 2017 um 16:05 Uhr


  • Dies ist die richtige Antwort. Die aufrufende Konvertierung für Gleitkommazahlen muss zwischen Ihrem Code und libc übereinstimmen. Es könnte immer noch mit einer Nichtübereinstimmung funktionieren, wenn Sie niemals Gleitkomma-Libc-Funktionen aufrufen.

    – Tor Klingeberg

    4. April 2017 um 17:11 Uhr

  • +1, da dies die richtigste Antwort zu sein scheint. Ich würde auch hinzufügen, dass Sie möglicherweise eine FPU haben oder nicht. Sie können auch eine FPU haben, die nur eine Teilmenge der Funktionen unterstützt, die in einem C-Programm ausgedrückt werden können, z 1.0L / 2.0L wäre auf einer Single-Precision-FPU aber nicht möglich 1.0f / 2.0f wäre. Es ist oft der Fall, dass die Compiler-Laufzeit (zB libgcc) die ‘weiche’ Version der fehlenden Long-Double-Division bereitstellt. Die Befehle mit einfacher Genauigkeit sind jedoch “weich” umschlossene Hardwarebefehle.

    – Silberkeuch

    14. Dezember 2021 um 5:49 Uhr


Es hört sich so an, als ob Ihre libc für Software-Gleitkommaoperationen erstellt wurde, während Ihre exe unter der Annahme von Hardwareunterstützung für Gleitkomma kompiliert wurde. Kurzfristig könnten Sie Soft Floats als Compiler-Flag erzwingen. (wenn Sie gcc verwenden, denke ich, es ist -msoft-float)

Wenn der Prozessor Ihres Ziels über Hardwareunterstützung für Gleitkommaoperationen verfügt, sollten Sie auf längere Sicht im Allgemeinen eine Cross-Toolchain mit aktiviertem Hardware-Float für Geschwindigkeit erstellen oder finden. Einige Prozessorfamilien haben Modellvarianten teils mit und teils ohne Hardwareunterstützung. Wenn Sie beispielsweise nur sagen, dass Ihr Prozessor ein ARM ist, reicht es nicht aus, um zu wissen, ob Sie Hardware-Gleitkommaunterstützung haben.

Die Berechnung kann entweder durch Gleitkomma-Hardware oder in Software auf der Basis von ganzzahliger Arithmetik durchgeführt werden.

In Hardware ist es 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 sein wird.

In einigen Controller-Familien, z. B. ARM, ist die Gleitkomma-Hardware in einigen Modellen der Familie vorhanden, in anderen nicht, daher unterstützt gcc für diese Familien beides. Ihr Problem scheint zu sein, dass Sie die beiden Optionen verwechselt haben.

Benutzeravatar von cigien
Zigien

Es kann der Fall sein, dass Softfloats die Daten allein in der fpu belassen, während Hardfloats den Overhead erfordern, die fpu-Register in den Cache zu verschieben, wenn der Prozess aktiv wird. Aus diesem Grund ist die FPU normalerweise zur Kompilierzeit für den Kernel deaktiviert. Verschwenden Sie keine Zyklen, indem Sie sie jedes Mal, wenn jemand einen Kernel aufruft, in den und aus dem Speicher schieben.

1421950cookie-checkWas ist der Unterschied zwischen harten und weichen Gleitkommazahlen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy