Schlüsselwort “registrieren” in C?

Lesezeit: 10 Minuten

Benutzeravatar von Nick Van Brunt
Nick van Brunt

Was bedeutet die register Schlüsselwort do in C-Sprache? Ich habe gelesen, dass es zur Optimierung verwendet wird, aber in keinem Standard klar definiert ist. Ist es noch relevant und wenn ja, wann würden Sie es verwenden?

  • Was macht das Schlüsselwort register in C? wird ignoriert 🙂

    – bestes

    25. Februar 2011 um 16:50 Uhr

  • @bestsss Nicht vollständig ignoriert. Versuchen Sie, eine Adresse zu bekommen register Variable.

    – qrdl

    14. Juni 2012 um 11:58 Uhr

  • Der Code, den Sie lesen, ist alt youtube.com/watch?v=ibF36Yyeehw#t=1827

    – Oberst Panik

    23. Dezember 2014 um 16:03 Uhr


Benutzeravatar von Brian Knoblauch
Brian Knoblauch

Es ist ein Hinweis für den Compiler, dass die Variable stark verwendet wird und dass Sie empfehlen, sie möglichst in einem Prozessorregister zu halten.

Die meisten modernen Compiler machen das automatisch und können sie besser auswählen als wir Menschen.

  • Nun, ich habe mit Register experimentiert, um meine ACM-Einreichungen zu optimieren, und manchmal hat es wirklich geholfen. Aber Sie müssen wirklich vorsichtig sein, denn schlechte Entscheidungen beeinträchtigen die Leistung.

    – ypnos

    23. Februar 2009 um 16:20 Uhr

  • Ein guter Grund nicht um ‘register’ zu verwenden: Sie können nicht die Adresse einer als ‘register’ deklarierten Variablen nehmen

    – Adam Rosenfield

    23. Februar 2009 um 16:21 Uhr

  • Beachten Sie, dass einige/viele Compiler das Schlüsselwort register vollständig ignorieren (was vollkommen legal ist).

    – Euro Mizellen

    23. Februar 2009 um 17:49 Uhr

  • ypnos: Tatsächlich hängt die Geschwindigkeit einer Lösung für ACM-ICPC-Probleme viel mehr von der Wahl des Algorithmus ab als von solchen Mikrooptimierungen. Das Zeitlimit von 5 Sekunden reicht normalerweise für eine korrekte Lösung aus, insbesondere wenn C anstelle von Java verwendet wird.

    – Joey

    15. Oktober 2009 um 13:12 Uhr

  • @Euro: Sie wissen das wahrscheinlich, aber nur um es explizit zu sagen, der Compiler muss die Adresse von a verhindern register Variable nicht genommen; Dies ist das nur zwingende Wirkung der register Stichwort. Auch dies reicht aus, um Optimierungen zu verbessern, da es trivial ist zu sagen, dass die Variable nur innerhalb dieser Funktion geändert werden kann.

    – Dale Hagglund

    9. Februar 2010 um 18:26 Uhr

Benutzeravatar von qrdl
qrdl

Ich bin überrascht, dass niemand erwähnt hat, dass Sie keine Adresse einer Registervariablen verwenden können, selbst wenn der Compiler beschließt, die Variable im Speicher und nicht im Register zu behalten.

Also verwenden register Sie gewinnen nichts (der Compiler entscheidet ohnehin selbst, wo die Variable abgelegt wird) und verlieren die & Betreiber – kein Grund, es zu verwenden.

  • Es gibt tatsächlich einen Grund. Die bloße Tatsache, dass Sie der Variablen keine Adresse entnehmen können, ergibt einige Optimierungsmöglichkeiten: Der Compiler kann beweisen, dass die Variable nicht gealiased wird.

    – Alexander C.

    9. Februar 2012 um 20:14 Uhr


  • Compiler sind notorisch schlecht darin zu beweisen, dass Aliasing in nicht trivialen Fällen nicht auftritt register ist dafür nützlich, auch wenn der Compiler es nicht in ein Register schreibt.

    – Meilen Route

    7. Juni 2014 um 5:33 Uhr

  • @AlexandreC, Miles, Compiler sind vollkommen in Ordnung, um zu überprüfen, ob & irgendwo von einer Variablen genommen wird. Unabhängig von anderen Schwierigkeiten beim Erkennen von Aliasing bringt Ihnen das Wiederholen nichts. Als K+R zum ersten Mal C erstellte, war es in der Tat nützlich zu wissen im Voraus dass & nicht verwendet würde, da dieser Compiler tatsächlich die Registerzuweisungsentscheidung getroffen hat, als er die Deklaration sah, bevor er sich den folgenden Code ansah. Deshalb gilt das Verbot. Das Schlüsselwort „register“ ist jetzt im Wesentlichen veraltet.

    – Gregor

    21. Februar 2015 um 22:31 Uhr


  • Nach dieser Logik const ist auch nutzlos, da es Ihnen nichts bringt, Sie verlieren nur die Möglichkeit, eine Variable zu ändern. register könnte verwendet werden, um sicherzustellen, dass niemand in Zukunft die Adresse einer Variablen ohne nachzudenken nimmt. Ich hatte noch nie einen Grund zu verwenden register obwohl.

    – Tor Klingeberg

    29. Oktober 2015 um 13:11 Uhr


Es weist den Compiler an, zu versuchen, ein CPU-Register anstelle von RAM zu verwenden, um die Variable zu speichern. Register befinden sich in der CPU und sind viel schneller zugänglich als RAM. Aber es ist nur ein Vorschlag für den Compiler und wird möglicherweise nicht ausgeführt.

  • Erwähnenswert für Leute, die C++ verwenden, C++ ermöglicht es Ihnen, die Adresse einer Registervariablen zu übernehmen

    – Werden

    30. März 2012 um 16:07 Uhr

  • @Will: … aber der Compiler wird das Schlüsselwort wahrscheinlich als Ergebnis ignorieren. Siehe meine Antwort.

    – bwDraco

    16. Dezember 2012 um 23:03 Uhr

  • Ja, es scheint, dass ‘register’ ein Placebo in C++ ist, es ist nur dazu da, C-Code als C++ zu kompilieren. Und es würde nicht viel Sinn machen, &var zu verbieten, während die Übergabe per Referenz oder const-Referenz erlaubt wird, und ohne Pass-by-Referenz haben Sie C++ ernsthaft beschädigt.

    – Gregor

    21. Februar 2015 um 22:23 Uhr

  • > “ohne Pass-by-Reference haben Sie C++ ernsthaft beschädigt“Ich habe so etwas nicht gemacht. Es war so, als ich es zum ersten Mal sah 😉

    – Benutzer426

    11. November 2021 um 1:43 Uhr

Benutzeravatar von bwDraco
bwDraco

Ich weiß, dass es bei dieser Frage um C geht, aber dieselbe Frage zu C++ wurde als exaktes Duplikat dieser Frage geschlossen. Diese Antwort gilt daher möglicherweise nicht für C.


Der neueste Entwurf des C++11-Standards, N3485sagt dies in 7.1.1/3:

EIN register Bezeichner ist ein Hinweis für die Implementierung, dass die so deklarierte Variable stark verwendet wird. [ note: The hint can be ignored and in most implementations it will be ignored if the address of the variable is taken. This use is deprecated … —end note ]

In C++ (aber nicht in C), sagt der Standard nicht, dass Sie nicht die Adresse einer deklarierten Variablen nehmen können register; Da jedoch eine Variable, die während ihrer gesamten Lebensdauer in einem CPU-Register gespeichert ist, keinen Speicherort hat, der ihr zugeordnet ist, wäre der Versuch, ihre Adresse zu nehmen, ungültig, und der Compiler wird die ignorieren register Schlüsselwort, um die Übernahme der Adresse zu ermöglichen.

Benutzeravatar von Paul Tomblin
Paul Tomblin

Es ist seit mindestens 15 Jahren nicht mehr relevant, da Optimierer diesbezüglich bessere Entscheidungen treffen als Sie. Selbst wenn es relevant war, machte es auf einer CPU-Architektur mit vielen Registern wie SPARC oder M68000 viel mehr Sinn als auf Intel mit seinem Mangel an Registern, von denen die meisten vom Compiler für seine eigenen Zwecke reserviert werden.

  • Compiler sind und bleiben erbärmlich darin, das Fehlen von Aliasing besser als der Entwickler zu erkennen, und daher sind Praktiken, die wiederholte Indirektion (sehr kostspielig) reduzieren und dabei helfen, Daten lokal zwischenzuspeichern, sehr relevant.

    – Benutzer426

    7. Juni um 16:13 Uhr

Ich habe gelesen, dass es zur Optimierung verwendet wird, aber in keinem Standard klar definiert ist.

In der Tat ist durch die C-Norm eindeutig definiert. Zitieren der Entwurf N1570 Ziffer 6.7.1 Absatz 6 (andere Fassungen haben denselben Wortlaut):

Eine Deklaration eines Bezeichners für ein Objekt mit Speicherklassenbezeichner register schlägt vor, dass der Zugriff auf das Objekt so schnell wie möglich erfolgt. Inwieweit solche Vorschläge wirksam sind, wird von der Umsetzung bestimmt.

Das Unäre & Der Operator darf nicht auf ein mit definiertes Objekt angewendet werden registerund register darf nicht in einer externen Deklaration verwendet werden.

Es gibt ein paar andere (ziemlich obskure) Regeln, die spezifisch für sind register-qualifizierte Objekte:

  • Definieren eines Array-Objekts mit register hat undefiniertes Verhalten.
    Korrektur: Es ist erlaubt, ein Array-Objekt mit zu definieren registeraber Sie können mit einem solchen Objekt nichts Nützliches tun (für die Indizierung in ein Array muss die Adresse seines Anfangselements genommen werden).
  • Das _Alignas specifier (neu in C11) darf auf ein solches Objekt nicht angewendet werden.
  • Wenn der Parametername an die übergeben wird va_start Makro ist register-qualifiziert, das Verhalten ist undefiniert.

Es mag noch ein paar andere geben; Laden Sie sich einen Entwurf der Norm herunter und suchen Sie bei Interesse nach “registrieren”.

Wie der Name schon sagt, die Original Bedeutung von register bestand darin, ein Objekt in einem CPU-Register zu speichern. Aber mit Verbesserungen bei der Optimierung von Compilern ist dies weniger nützlich geworden. Moderne Versionen des C-Standards beziehen sich nicht auf CPU-Register, weil sie nicht mehr davon ausgehen (müssen), dass es so etwas gibt (es gibt Architekturen, die keine Register verwenden). Die allgemeine Weisheit ist die Anwendung register zu einer Objektdeklaration ist wahrscheinlicher verschlechtern den generierten Code, weil er die eigene Registerzuordnung des Compilers stört. Es könnte immer noch ein paar Fälle geben, in denen es nützlich ist (wenn Sie zum Beispiel wirklich wissen, wie oft auf eine Variable zugegriffen wird, und Ihr Wissen besser ist als das, was ein moderner optimierender Compiler herausfinden kann).

Die wichtigste greifbare Wirkung von register ist, dass es jeden Versuch verhindert, die Adresse eines Objekts zu nehmen. Dies ist als Optimierungshinweis nicht besonders nützlich, da es nur auf lokale Variablen angewendet werden kann und ein optimierender Compiler selbst sehen kann, dass die Adresse eines solchen Objekts nicht verwendet wird.

  • Compiler sind und bleiben erbärmlich darin, das Fehlen von Aliasing besser als der Entwickler zu erkennen, und daher sind Praktiken, die wiederholte Indirektion (sehr kostspielig) reduzieren und dabei helfen, Daten lokal zwischenzuspeichern, sehr relevant.

    – Benutzer426

    7. Juni um 16:13 Uhr

Benutzeravatar von Rupert
Rupert

Tatsächlich teilt register dem Compiler mit, dass die Variable mit nichts anderem im Programm (nicht einmal mit char) aliasiert wird.

Das kann von modernen Compilern in einer Vielzahl von Situationen ausgenutzt werden und kann dem Compiler bei komplexem Code ziemlich helfen – bei einfachem Code können die Compiler dies selbst herausfinden.

Andernfalls hat es keinen Zweck und wird nicht zur Registerzuordnung verwendet. Es führt normalerweise nicht zu Leistungseinbußen, um es anzugeben, solange Ihr Compiler modern genug ist.

  • “sagt dem Compiler …” nein, tut es nicht. Alle Auto-Variablen haben diese Eigenschaft, es sei denn, Sie nehmen ihre Adresse und es in einer Weise zu verwenden, die bestimmte analysierbare Verwendungen überschreitet. Der Compiler kennt dies also aus dem Code, unabhängig davon, ob Sie das Schlüsselwort register verwenden. Es kommt vor, dass das Schlüsselwort ‘register’ das Schreiben eines solchen Konstrukts illegal macht, aber wenn Sie das Schlüsselwort and nicht Nehmen Sie die Adresse so, dann weiß der Compiler immer noch, dass sie sicher ist. Solche Informationen sind entscheidend für die Optimierung.

    – Gregor

    21. Februar 2015 um 22:39 Uhr

  • @greggo: Schade register verbietet überhaupt, die Adresse zu nehmen, da es sonst nützlich sein könnte, Compiler über Fälle zu informieren, in denen ein Compiler in der Lage wäre, Registeroptimierungen anzuwenden Trotz die Adresse einer Variablen an eine externe Funktion übergeben wird (die Variable müsste in den Speicher geleert werden für diesen speziellen Anrufaber sobald die Funktion zurückkehrt, könnte der Compiler sie wieder als Variable behandeln, deren Adresse noch nie verwendet wurde).

    – Superkatze

    26. Mai 2016 um 23:11 Uhr

  • @supercat Ich denke, es wäre immer noch ein sehr schwieriges Gespräch mit dem Compiler. Wenn Sie das dem Compiler mitteilen möchten, können Sie dies tun, indem Sie die erste Variable in eine zweite kopieren, die kein ‘&’ enthält, und dann die erste nie wieder verwenden.

    – Gregor

    30. Mai 2016 um 19:38 Uhr

  • @greggo: Das sagen, wenn bar ist ein register Variable, ein Compiler kann nach Belieben ersetzen foo(&bar); mit int temp=bar; foo(&temp); bar=temp;aber unter der Adresse von bar in den meisten anderen Zusammenhängen verboten wäre, scheint keine allzu komplizierte Regel zu sein. Wenn die Variable ansonsten in einem Register gehalten werden könnte, würde die Substitution den Code kleiner machen. Wenn die Variable sowieso im RAM gehalten werden müsste, würde die Substitution den Code größer machen. Die Frage, ob die Ersetzung dem Compiler überlassen werden soll, würde in beiden Fällen zu besserem Code führen.

    – Superkatze

    31. Mai 2016 um 14:28 Uhr

  • @greggo: Zulassen a register Eine Qualifizierung für globale Variablen, unabhängig davon, ob der Compiler die Übernahme der Adresse zulässt oder nicht, würde einige nette Optimierungen in Fällen ermöglichen, in denen eine eingebettete Funktion, die eine globale Variable verwendet, wiederholt in einer Schleife aufgerufen wird. Ich kann mir keine andere Möglichkeit vorstellen, diese Variable zwischen Schleifeniterationen in einem Register zu halten – können Sie?

    – Superkatze

    31. Mai 2016 um 14:30 Uhr

1426990cookie-checkSchlüsselwort “registrieren” in C?

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

Privacy policy