Warum wird diese C ++ - Memberfunktion nicht vom Compiler mit -O3 optimiert?

9

Die norm -Memberfunktion in der C ++ vector -Klasse, die unten deklariert wird, ist als const markiert und (soweit ich das beurteilen kann) enthält keine Nebenwirkungen.

%Vor%

Wenn ich norm mehrere Male bei einer const Instantiierung von vector (siehe test Funktion oben) mit dem gcc Compiler (Version 5.4) und Optimierungen (zB -O3 ) dann den Compiler aufrufen inline norm , berechnet aber immer noch das Ergebnis von norm , obwohl sich das Ergebnis nicht ändern sollte. Warum optimiert der Compiler den zweiten Aufruf von norm nicht und berechnet dieses Ergebnis nur einmal? Diese Antwort scheint darauf hinzuweisen, dass der Compiler diese Optimierung durchführen sollte, wenn der Compiler feststellt, dass die Funktion norm keine hat Nebenwirkungen. Warum passiert das nicht in diesem Fall?

Beachten Sie, dass ich feststelle, was der Compiler mit dem Compiler-Explorer erzeugt und dass die Assembly-Ausgabe für gcc Version 5.4 ist unten angegeben. Der Claming Compiler gibt ähnliche Ergebnisse. Beachten Sie auch, dass, wenn ich die Compilerattribute von gcc benutze, um norm als const-Funktion mit __attribute__((const)) manuell zu markieren, der zweite Aufruf so optimiert wird, wie ich wollte, aber meine Frage ist, warum gcc (und clang) das nicht tun automatisch, da die norm Definition verfügbar ist?

%Vor%     
Martin Robinson 06.03.2017, 06:37
quelle

1 Antwort

4
___ tag123gcc ___ GCC ist die GNU Compiler-Sammlung. Es ist der De-facto-Standard-C-Compiler unter Linux und unterstützt auch viele andere Sprachen und Plattformen. ___ tag123optimierung ___ Optimierung ist der Akt der Verbesserung einer Methode oder eines Designs. In der Programmierung nimmt die Optimierung normalerweise die Form an, die Geschwindigkeit eines Algorithmus zu erhöhen oder die benötigten Ressourcen zu reduzieren. Eine weitere Bedeutung der Optimierung sind numerische Optimierungsalgorithmen. ___ tag123clang ___ clang ist ein C-, C ++ - und Objective-C-Compiler, der Vorverarbeitung, Parsing, Optimierung,        Codegenerierung, Assemblierung und Verknüpfung. Abhängig davon, welche High-Level-Moduseinstellung bestanden wird, Clang        wird angehalten, bevor eine vollständige Verbindung hergestellt wird. Während Clang hoch integriert ist, ist es wichtig zu verstehen        die Phasen der Kompilation, um zu verstehen, wie man sie aufruft. ___ tag123c ___ C ++ ist eine universelle Programmiersprache. Es wurde ursprünglich als Erweiterung von C entworfen und behält eine ähnliche Syntax, ist aber jetzt eine komplett andere Sprache. Verwenden Sie dieses Tag für Fragen zu Code, der mit einem C ++ - Compiler kompiliert werden soll. ___ qstnhdr ___ Warum wird diese C ++ - Memberfunktion nicht vom Compiler mit -O3 optimiert? ___ qstntxt ___

Die norm -Memberfunktion in der C ++ -Os -Klasse, die unten deklariert wird, ist als -O2 -fdump-tree-all markiert und (soweit ich das beurteilen kann) enthält keine Nebenwirkungen.

%Vor%

Wenn ich vector<N>::norm() mehrere Male bei einer .local-pure-const1 Instantiierung von .einline (siehe norm Funktion oben) mit dem gcc Compiler (Version 5.4) und Optimierungen (zB __attribute__ ((noinline)) ) dann den Compiler aufrufen inline %code% , berechnet aber immer noch das Ergebnis von %code% , obwohl sich das Ergebnis nicht ändern sollte. Warum optimiert der Compiler den zweiten Aufruf von %code% nicht und berechnet dieses Ergebnis nur einmal? Diese Antwort scheint darauf hinzuweisen, dass der Compiler diese Optimierung durchführen sollte, wenn der Compiler feststellt, dass die Funktion %code% keine hat Nebenwirkungen. Warum passiert das nicht in diesem Fall?

Beachten Sie, dass ich feststelle, was der Compiler mit dem Compiler-Explorer erzeugt und dass die Assembly-Ausgabe für gcc Version 5.4 ist unten angegeben. Der Claming Compiler gibt ähnliche Ergebnisse. Beachten Sie auch, dass, wenn ich die Compilerattribute von gcc benutze, um %code% als const-Funktion mit %code% manuell zu markieren, der zweite Aufruf so optimiert wird, wie ich wollte, aber meine Frage ist, warum gcc (und clang) das nicht tun automatisch, da die %code% Definition verfügbar ist?

%Vor%     
___ answer42627556 ​​___

Der Compiler kann das Ergebnis von %code% berechnen und mehrfach verwenden. Z.B. mit dem Schalter %code% :

%Vor%

Die fehlende Optimierung ist nicht auf nicht-assoziativen Gleitkomma zurückzuführen -math oder einige beobachtbare- Verhaltensproblem .

  

In einer nicht ordnungsgemäß mutexierten Umgebung kann eine andere Funktion den Inhalt des Arrays zwischen den Aufrufen von norm

ändern

Es kann passieren, aber es ist kein Problem für den Compiler (z. B. Ссылка ).

Wenn Sie das Beispiel mit dem Schalter %code% zusammenstellen, sehen Sie Folgendes:

  • g ++ erkennt %code% korrekt als reine Funktion (Ausgabedatei %code% );
  • Inlining passiert in frühen Stadien (Ausgabedatei %code% ).

Beachten Sie auch, dass die Markierung von %code% mit %code% des Compilers CSE ausführt:

%Vor%

Marc Glisse ist (wahrscheinlich) richtig.

Eine erweiterte Form der gemeinsamen Unterausdruckeliminierung ist erforderlich, um den wiederkehrenden Ausdruck zu entfernen / a>.

    
___
manlio 06.03.2017, 14:00
quelle

Tags und Links