double auf 32-Bit-Rechner



  • Hallo,

    ich habe eine Frage, die nicht direkt etwas mit C++ zu tun hat 🙂 Ich hoffe das ist nicht all zu schlimm. Meine Frage ist Folgende: Ein Double hat ja 64-Bit. Wie kann ein double dann auf einem 32-Bit-Rechner dargestellt werden?

    Grüßle,
    Jessy 🙂



  • Wie das im Detail gemacht wird haengt stark von der Implementierung einer 32-bit Architektur ab. Aber wenn du 32-bit Register hast, dann brauchst du zwei Register, um eine 64-bit Variable zu speichern. Die unteren 32 Bits speicherst du in einem Register und die oberen 32 Bits speicherst du in einem Register. Natuerlich werden dann die Operationen auf diesen Variabeln komplizierter. Das kann einen Overhead erzeugen.

    Ich nehme an bei CISC Architekturen gibt es Instruktionen, die auf 64bit Variablen arbeiten koennen. Bei RISC Architekturen fehlt dies oftmals und dann muss der Compiler (oder der Programmierer, falls er mit Assembly arbeitet) halt dieses Verhalten selber nachbauen.

    Diese Erklaerung ist nicht wirklich exakt aber es gibt einem eine Vorstellung wie das in etwa funktioniert.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Themen rund um den PC verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Die x86-FPU hat eigene Register, und die sind mindestens 64bit breit.



  • @icarus2
    Vielleicht solltest du keine Dinge erklären bei denen du dich nicht wirklich auskennst.
    Die FPU hat wie Ethon schon sagte eigene Register, die breit genug sind.
    Und *die* CISC Chip-Familie schlechthin (=x86) hat auch keine feinen Befehle um mit 64 Bit Zahlen zu arbeiten. Und... selbst wenn ein CISC entsprechende Befehle hätte, der Overhead wäre dadurch nicht vewrschwunden, denn diese Befehle würden einfach entsprechend lange dauern -- zumindest so lange der CISC kein 64 Bit Rechenwerk hat.

    EDIT: Korrektur: x86 hat (fast) keine Befehle um mit 64 Bit Zahlen in Registerpaaren zu arbeiten. Ab SSE2 gibt's dann die Möglichkeit in den SSE Registern mit 64 Bit Zahlen zu rechnen - dann geht das auch relativ flott.



  • Die x86-FPU arbeitet m.W. intern grundsätzlich mit 80 Bit. Wenn man dort ein 64-bit-double reinladen will, sind das einfach zwei 32-Bit-Transfers hintereinander.



  • Bashar schrieb:

    Die x86-FPU arbeitet m.W. intern grundsätzlich mit 80 Bit. Wenn man dort ein 64-bit-double reinladen will, sind das einfach zwei 32-Bit-Transfers hintereinander.

    Ja, die arbeitet leider intern immer mit 80Bit. Aber die FPU hat eine Anweisung um bist zu 80Bit direkt zu laden (fld*/fst*). Man muss also nicht selbst die Zahl in zwei (bzw. drei) Schritten laden. Mit SSE kann man aber echte Single oder Doubleprecision haben. Daher sollte man beim kompilieren möglichst darauf achten, dass der Compiler SSE- und nicht x87-Anweisungen generiert.



  • Sorry, das hätte mir klar sein können, dass es undeutlich ausgedrückt war. Es ist tatsächlich immer nur eine FLD-Instruktion; ich meinte das, was dabei unter der Haube passiert.



  • Man könnte ein 64 Bit double auch ganz gut auf einem 8 Bit System darstellen.

    Man liest z.B. die Eingabe byteweise (oder eben registerbreit) in den Speicher. Und der Speicher hat definitiv schon mal mehr als 64 Bit 😉

    Normalerweise haben Pentiums einen extra mathematischen Co-Prozessor, die FPU, an Bord, und in diese wird die 64 Bit breite Variable vom Speicher aus in einem Rutsch hineingelesen.
    Die FPU rechnet im Stapelbetrieb und schreibt nach Befehl das Ergebnis zurück in den Speicher.
    (Früher mussten aber einige Rechner die FPU emulieren (mit 16Bit!)

    Die Ausgabe der Variablen kann man nun auch wieder byteweise erledigen, wenn man will.

    Und wenn man mit noch breiteren Werten als 64 Bit rechnen möchte, dann ginge das genauso, wie man es eben handschriftlich machen würde. Aber hier gibt es dann auch optimierte Algos für Computerrechnereien, z.B.
    http://de.wikipedia.org/wiki/Karatsuba-Algorithmus

    In neueren Systemen kann man über SSE/AVX (auch von 32 Bit aus)
    auf 128 Bit oder 256 Bit zum Rechnen zurückgreifen, wenn man es braucht, oder eben auf Grafikkarten, solange die Rechnerei innerhalb stattfinden kann.



  • hustbaer schrieb:

    @icarus2
    Vielleicht solltest du keine Dinge erklären bei denen du dich nicht wirklich auskennst.

    Ja, da hast du recht. Ein Studienkollege hat mir das mal so - offenbar falsch - erklaert.

    hustbaer schrieb:

    Und... selbst wenn ein CISC entsprechende Befehle hätte, der Overhead wäre dadurch nicht vewrschwunden, denn diese Befehle würden einfach entsprechend lange dauern -- zumindest so lange der CISC kein 64 Bit Rechenwerk hat.

    Das ist mir klar. Habe mich da ungeschickt ausgedrueckt.

    Zwei Fragen habe ich noch dazu:
    1.
    Wieso verwenden die FPUs gerade 80 Bits?

    Soweit ich weiss haben Smartphones keine FPUs. Und ich nehme nicht an, dass das alles 64bit Systeme sind. Wie wird das dort gemacht?



  • icarus2 schrieb:

    hustbaer schrieb:

    @icarus2
    Vielleicht solltest du keine Dinge erklären bei denen du dich nicht wirklich auskennst.

    Ja, da hast du recht. Ein Studienkollege hat mir das mal so - offenbar falsch - erklaert.

    Ja, keine Tragik 🙂
    Ich hab' ja selber nen Fehler gemacht, siehe mein EDIT. x86 kann natürlich 64 Bit, aber halt nicht vor SSE2 - was aber mittlerweile alt genug ist, dass man es als Standard ansehen sollte.

    Zwei Fragen habe ich noch dazu:
    1.
    Wieso verwenden die FPUs gerade 80 Bits?

    http://en.wikipedia.org/wiki/Extended_precision

    The double extended format was designed not to store data at higher precision as such, but rather primarily to allow for the computation of double results more reliably and accurately by minimising overflow and roundoff-errors in intermediate calculations [7][8]: for example, many floating point algorithms (e.g. exponentiation) suffer from significant precision loss when computed using the most direct implementations. To mitigate such issues the internal registers in the 8087 were designed to hold intermediate results in an 80-bit "extended precision" format. (...)

    Also in Kurz: 64 Bit is der IEEE Standard in dem man gerne abspeichern möchte, und dessen Präzision man auch gerne (für die Endresultate) ausnutzen möchte. Da man beim Rechnen Präzision verliert, ham se die Register breiter gemacht.
    Damals durchaus sinnvoll, da FPU Gedöns noch viel in Assembler programmiert wurde. Da kann man die breiteren Register dann schön ausnutzen.
    Heute nimmer so prickelnd, da man kaum gut kontrollieren kann an welchen Punkten im Programm ein Transfer in oder aus dem Hauptspeicher passieren wird, und dadurch auf 64 trunkiert wird. Die Präzision einer Berechnung ist also zum Würfelspiel geworden. Daher haben Befehlssätze wie SSE2 auch nen Vorteil: man hat zwar weniger Präzision, dafür aber immer die selbe, egal (*) was der Compiler macht.

    *: Natürlich nicht ganz egal was der Compiler macht - "x/10.0" durch "x * 0.1" zu ersetzen o.ä. macht natürlich immer noch einen Unterschied.

    Soweit ich weiss haben Smartphones keine FPUs. Und ich nehme nicht an, dass das alles 64bit Systeme sind. Wie wird das dort gemacht?

    Also ich *weiss* diesbezüglich gar nix, aber es würde mich sehr sehr wundern wenn die keine FPU hätten. Ich meine pfuh, wie soll das mit den modernen 3D Games funktionieren die es ja durchaus für diese Plattformen gibt? Die werden ja wohl nicht alles mit Shadern rechnen (speziell Kollisionsabfragen etc.).



  • Danke fuer den Link und die Erklaerung. Ich werde mir den Wikipedia Artikel heute noch genauer durchlesen wenn ich die Zeit dazu finde.

    hustbaer schrieb:

    Also ich *weiss* diesbezüglich gar nix, aber es würde mich sehr sehr wundern wenn die keine FPU hätten. Ich meine pfuh, wie soll das mit den modernen 3D Games funktionieren die es ja durchaus für diese Plattformen gibt? Die werden ja wohl nicht alles mit Shadern rechnen (speziell Kollisionsabfragen etc.).

    Ich habe mal danach gegoogelt und bin dabei auf folgendes gestossen:

    Ein Paper ueber Augmeneted Reality on Android Smartphones aus dem Jahr 2010. Ich habe nicht das ganze durchgelesen aber auf Seite 15 steht am Ende der Steite

    Due to restrictions in size and power consumptions, most of todays embedded proces-
    sors found in smartphones lack a FPU. So does the HTC Dream, used for this paper.
    As stated in [23] applications will run 5-10 times slower on mobile phones than on a average PC due to hardware limitations.

    Und auf Stackoverflow meinte jemand folgendes im Jahr 2011:

    Many, perhaps most, Android devices have no floating-point co-processor.

    Offenbar kommt es doch vor, dass Smartphones keine FPUs haben. Die muessen das dann (steht im Paper) mit Software emulieren.



  • Hihi, ja hast Recht. Krass.
    Windows 7 Phones und die Eier haben aber anscheinend alle float in Hardware.



  • Wenn du keine Floatingpoint Einheit hast, dann musst du entweder schauen, dass du alles mit Fixedpoint löst oder sehr aufwendig Floatingpoint simulieren. Ich denke, dass die meisten Smartphones aber eine FPU haben und mittlerweile dürfte selbst SIMD/NEON verbreitet sein. Der spricht sicher von den billig Androids, die ja nicht wirklich Smartphones sind.


Anmelden zum Antworten