Größe des CPU-Registers

Lesezeit: 4 Minuten

Es ist normalerweise besser, CPU-Register mit ihrer vollen Kapazität zu nutzen. Für ein portables Stück Code bedeutet dies die Verwendung von 64-Bit-Arithmetik und -Speicherung auf einer 64-Bit-CPU und nur 32-Bit auf einer 32-Bit-CPU (andernfalls werden 64-Bit-Anweisungen im 32-Bit-Modus emuliert, was zu verheerende Leistungen).

Das bedeutet, dass es notwendig ist, die Größe der CPU-Register zu erkennen, typischerweise zur Kompilierzeit (da Laufzeittests teuer sind).

Seit Jahren verwende ich die einfache Heuristik sizeof(nativeRegisters) == sizeof(size_t).

Es hat für viele Plattformen gut funktioniert, aber es scheint eine falsche Heuristik für Linux zu sein x32 : in diesem Fall, size_t ist nur 32 Bit, während Register immer noch 64 Bit verarbeiten könnten. Dies führt zu einer verlorenen Leistungsmöglichkeit (wichtig für meinen Anwendungsfall).

Ich möchte die nutzbare Größe von CPU-Registern auch in einer solchen Situation korrekt erkennen.

Ich vermute, ich könnte versuchen, ein Compiler-spezifisches Makro für Sonderfälle zu finden x32 Modus. Aber ich habe mich gefragt, ob es etwas Allgemeineres geben würde, um mehr Situationen abzudecken. Ein anderes Ziel wäre zum Beispiel OpenVMS 64-Bit: Dort beträgt die native Registergröße 64-Bit, aber size_t ist nur 32 Bit.

  • Unser Interesse, wie können Sie “die Antwort” in C – Assembly verwenden, die ich bekomme, aber C?

    – John3136

    30. April 2016 um 8:12 Uhr

  • Es liegt am Algorithmus. Verwenden Sie eine genauere 64-Bit-Arithmetik anstelle einer billigeren 32-Bit-Heuristik. Verwenden Sie Register als “schnellen lokalen Speicher” für längere Zeit, wenn 64-Bit im Vergleich zu 32-Bit verwendet werden. Die Auswahl erfolgt zur Kompilierzeit mit test of sizeof(size_t) (bis jetzt).

    – Cyan

    30. April 2016 um 8:14 Uhr

  • Ein weiterer beliebter ist sizeof(void*).

    – Sergej Kalinitschenko

    30. April 2016 um 8:22 Uhr

  • Es gibt keine zuverlässige Möglichkeit, die Registergröße von der einfachen C-Ebene aus zu ermitteln. Aber von den Definitionen der Sprache sollte die nächste Vermutung sein sizeof(int) wie int soll der natürliche Typ für die Umwelt sein. (Andere Typen sind bereits an einen anderen Zweck gebunden.) Auch dann werden Ihnen einige Compiler-Einstellungen folgen.

    – rpi

    30. April 2016 um 8:44 Uhr


  • @rpy: In Linux, Windows und MacOS X für 64-Bit-Ziele sizeof(int)==4 wie in ihren ABIs definiert. Also nein, int ist kein guter Indikator. Dann unter Windows sizeof(long)==4 und unter Linux sizeof(long)==8.

    – Datenwolf

    30. April 2016 um 10:55 Uhr

Benutzer-Avatar
Keith Thompson

Es gibt keinen zuverlässigen und tragbaren Weg, um die Registergröße von C zu bestimmen. C hat nicht einmal ein Konzept von “Registern” (die Beschreibung der register Schlüsselwort erwähnt keine CPU-Register).

Aber es definiert eine Reihe von Integer-Typen, die die sind am schnellsten Art von mindestens einer bestimmten Größe. <stdint.h> definiert uint_fastN_tzum N = 8, 16, 32, 64.

Wenn Sie davon ausgehen, dass Register mindestens 32 Bit haben, dann uint_fast32_t hat wahrscheinlich die gleiche Größe wie ein Register, entweder 32 oder 64 Bit. Dies ist nicht garantiert. Hier ist, was die Norm sagt:

Jeder der folgenden Typen bezeichnet einen ganzzahligen Typ, mit dem normalerweise am schnellsten gearbeitet werden kann, unter allen ganzzahligen Typen, die mindestens die angegebene Breite haben.

mit Fußnote:

Es ist nicht garantiert, dass der angegebene Typ für alle Zwecke am schnellsten ist; Wenn die Implementierung keinen klaren Grund hat, einen Typ einem anderen vorzuziehen, wählt sie einfach einen ganzzahligen Typ aus, der die Vorzeichen- und Breitenanforderungen erfüllt.

In der Tat schlage ich vor, dass Sie die verwenden [u]int_fastN_t types drückt Ihre Absicht deutlicher aus als der Versuch, die CPU-Registergröße anzupassen.

Wenn das für ein bestimmtes Ziel nicht funktioniert, müssen Sie einen Sonderfall hinzufügen
#if oder #ifdef Anweisungen zur Auswahl eines geeigneten Typs. Aber uint_fast32_t (oder uint_fast16_t wenn Sie 16-Bit-Systeme unterstützen möchten) ist wahrscheinlich ein besserer Ausgangspunkt als size_t oder int.

Ein schnelles Experiment zeigt das, wenn ich mit kompiliere gcc -mx32beide uint_fast16_t und uint_fast32_t sind 32 Bit. Sie sind beide 64 Bit, wenn sie ohne kompiliert werden -mx32 (auf meinem x86_64-System). Was bedeutet, dass zumindest für gcc die uint_fastN_t Typen nicht Tun Sie, was Sie wollen. Sie benötigen einen Sonderfallcode für x32. (Wahrscheinlich gcc sollte Verwenden Sie 64-Bit-Typen für uint_fastN_t im x32-Modus. Ich habe gerade diese Frage gepostet und danach gefragt.)

Diese Frage fragt, wie eine x32-Umgebung im Präprozessor erkannt werden kann. gcc bietet keine direkte Möglichkeit, dies festzustellen, aber ich habe gerade eine Antwort gepostet, die die Verwendung von vorschlägt __x86_64__ und SIZE_MAX Makros.

  • Das ist eine großartige vollständige Antwort. Ich werde mich für die vorgeschlagene Makrolösung entscheiden.

    – Cyan

    1. Mai 2016 um 5:06 Uhr

  • „Wenn Sie davon ausgehen, dass Register mindestens 32 Bit lang sind“ – Die Suche nach einer plattformunabhängigen Lösung sollte etwas bedeuten, das auch für 8- und 16-Bit-Prozessoren für kleine eingebettete Systeme funktioniert.

    – Craig McQueen

    6. August 2020 um 5:26 Uhr

  • Mir ist aufgefallen, dass Linux-Kernel-Strukturen, wie z struct vm_area_structverwenden unsigned long um virtuelle Speicheradressen zu halten. Gibt es dafür eine Garantie sizeof(long) ist mindestens die Größe eines Registers?

    – Daniel Walker

    26. August 2021 um 17:38 Uhr

  • @DanielWalker Nein, es gibt keine solche Garantie (tatsächlich hat C kein Konzept eines “Registers”, trotz des Vorhandenseins der register Stichwort). Linux-Kernel-Code ist nicht portierbar (weil es nicht sein muss). Es wird nur mit gcc oder vielleicht etwas Kompatiblem kompiliert.

    – Keith Thompson

    26. August 2021 um 17:43 Uhr

1229150cookie-checkGröße des CPU-Registers

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

Privacy policy