2008-11-24 10 views
28

Ich lese durch K & R und kam zu dem kleinen Abschnitt über Registervariablen und fragte mich, ob die Leute hier ein paar gute Beispiele dafür in die Praxis umgesetzt haben.Was ist ein gutes Beispiel für die Verwendung von Registervariablen in C?

Aus Abschnitt 4.7 in K & R:

Die Register Erklärung sieht aus wie
Register int x;
Register Zeichen c;

Um klar zu sein, ich hoffe nur, einige coole Code-Beispiele zu sehen. Ich bin mir ziemlich sicher, dass ich das Thema verstehe, so dass ich nicht die Notwendigkeit verspüre, eine ausführliche Erklärung einzutippen (außer du willst es).

Antwort

64

Es gibt kein gutes Beispiel für die Registerbenutzung bei der Verwendung moderner Compiler (lesen Sie: letzte 15+ Jahre), weil es fast nie etwas nützt und etwas schlecht machen kann. Wenn Sie register verwenden, sagen Sie dem Compiler "Ich weiß, wie ich meinen Code besser optimieren kann als Sie", was fast nie der Fall ist. Eine der drei Dinge kann passieren, wenn Sie register verwenden:

  • Der Compiler ignoriert es, das ist höchstwahrscheinlich. In diesem Fall besteht der einzige Nachteil darin, dass Sie die Adresse der Variablen nicht im Code verwenden können.
  • Der Compiler berücksichtigt Ihre Anfrage und der Code läuft daher langsamer.
  • Der Compiler ehrt Ihre Anfrage und der Code läuft schneller, dies ist das unwahrscheinlichste Szenario.
  • Auch wenn ein Compiler bei der Verwendung von register besseren Code erzeugt, gibt es keinen Grund zu der Annahme, dass ein anderer dasselbe tut. Wenn Sie etwas kritischen Code haben, den der Compiler nicht gut genug optimiert, ist es wahrscheinlich am besten, Assembler für diesen Teil zu verwenden, aber natürlich ist das passende Profiling, um den generierten Code zu verifizieren, wirklich ein Problem.

    +3

    "Drei Dinge können passieren, und zwei sind schlecht"? Wo habe ich das schon mal gehört ... ;-) –

    +0

    Denken Sie daran, dass der Compiler vollkommen frei ist, Ihren Vorschlag zu ignorieren - es gibt nichts im Standard zu sagen, dass er eine Registervariable in ein Register setzen muss. –

    +0

    könnte auch der Fall sein, dass Sie ein Compiler-Backend schreiben und Sie sagen "Register" für alle Locals in einer Funktion wird eine stackless-Funktion machen. das wäre sehr nützlich, denke ich. –

    10

    Im Allgemeinen stimme ich mit Robert überein, aber wie jede gute Regel hat dieser auch Ausnahmen.
    Wenn Sie auf tief eingebetteten System arbeiten, wissen Sie vielleicht besser als Compiler, wie Sie den Code für Ihre spezifische Anwendung auf Ihre spezifische Hardware-Architektur optimieren.

    Aber in 99% der Fälle ist Roberts Erklärung gut für eingebettete Wörter.

    +2

    Das sieht ziemlich genau so aus, wie Robert es ausdrückte. –

    +0

    Eigentlich hast du recht. Ich las den Beitrag erneut und der letzte Absatz klärt auf, was ich klären wollte ... Nächstes Mal werde ich besser lesen – Ilya

    3

    Ein weiterer häufiger Fall ist die Implementierung von Low-Level-Interpretern. Einige Zustände in Registern halten, z. virtual machine stack pointer, kann den Speicherzugriff erheblich reduzieren und den Code beschleunigen.

    Ein Beispiel für die Optimierung finden Sie unter vmgen — a generator of efficient virtual machine interpreters (5.2 Top of Stack Caching).

    1

    Zuerst ist, sollte Register-Variable für stark verwendete Variablen wie Regelkreis Variable verwendet werden, um die Leistung durch Minimierung der Zugriffszeit zu verbessern.sekundäre können Sie nur verwenden und nur Speicher-Spezifizierer in dieser Situation registrieren like, Spaß (auto int a, auto int b): Fehler Spaß (Register int a, Register int b): nur das würde nur ausgeführt Spaß (statisch Int a, statisch int b): Fehler fun (extern int a, extern int b): Fehler

    +3

    Was ?! Der K & R-Text stammt aus den 1970er Jahren, daher sind einige ihrer Empfehlungen etwas veraltet. "Register" ist definitiv einer von denen. –

    4

    Ich weiß, das ist von einiger Zeit, aber hier ist eine Implementierung einer Unterprozedur von Heapsort, in dem die Verwendung von registrieren Variablen der Algorithmus schneller macht, zumindest 4.5.2 mit gcc den Code

    inline void max_heapify(int *H, int i){ 
        char OK = FALSE; 
        register int l, r, max, hI; 
        while(!OK){ 
         OK = TRUE; 
         l = left(i); 
         r = right(i); 
         max = i; 
         if(l <= H[SIZE] && H[l] > H[i]){ 
          max = l; 
         } 
         if(r <= H[SIZE] && H[r] > H[max]){ 
          max = r; 
         } 
         if(max != i){ 
          OK = FALSE; 
          hI = H[i]; 
          H[i] = H[max]; 
          H[max] = hI; 
          i = max; 
         } 
        } 
    } 
    

    ich die algortihm getestet zu kompilieren mit und w Ohne das Schlüsselwort register vor den Attributen und ausgeführt, um ein zufälliges Array mit 50.000.000 Elementen auf meinem Notebook ein paar Mal für jede Version zu sortieren.

    Die Verwendung von Registern ließ die Heapsort-Zeit von ~ 135s auf ~ 125s fallen.

    Ich habe auch nur mit 5.000.000 Elementen getestet, aber es mehrmals ausgeführt.

    Die Version ohne das Register begann bei 11s aber jede Ausführung verringert sich die Zeit, bis er 9,65s erreicht und hielt es

    die Version mit dem Register begann bei 10s und senkte die Zeit bis 8,80s.

    Ich denke, es hat etwas mit dem Cache-Speicher zu tun. Nichtsdestoweniger scheint es, dass die Register den Algorithmus um einen Konstantenfaktor schneller machen. Da diese Variablen ziemlich häufig in dem Algorithmus verwendet werden, indem sichergestellt wird, dass sie auf dem Register sind, anstatt diese Arbeit dem Compiler zu überlassen, führte dies zu einem besseren Ergebnis Fall. Allerdings hat es die Zeit nicht so sehr verbessert.

    Hoffentlich wird Thill für jemanden hilfreich sein, Grüße.

    +3

    Um Ihr Benchmarking ernst zu nehmen, sollten Sie Informationen darüber bereitstellen, wie Sie es kompiliert haben (welche Flags), auf welcher Plattform Sie es ausgeführt haben und vielleicht einige Details über Ihre Architektur und/oder CPU. Wie du rankst, ist max_heapify auch wichtig. – raylu