Visual C ++ ~ Inlining einfache const Funktionszeiger Aufrufe

8

Lieber StackOverflowers,

Ich habe ein einfaches Stück Code, das ich in Microsoft Visual Studio C ++ 2012 kompiliere:

%Vor%

Der Compiler generiert den folgenden Code:

%Vor%

Ich habe dies für die 'Full optimisation' (/ Obx Flag) und 'Any Passeng' für die Inline-Funktion Expansion zusammengestellt. (/ Ob2-Flag)

Ich habe mich gefragt, warum der Compiler diesen Aufruf nicht inline aufruft, weil er const ist. Hat jemand von euch eine Idee, warum es nicht inline ist und ob es möglich ist, den Compiler inline zu machen?

Christ

BEARBEITEN: Ich führe jetzt einige Tests aus, und MSVC kann die Funktionszeiger auch nicht einbinden, wenn:

- Ich bewege den const-Zeiger aus der Klasse und mache ihn global.

- Ich bewege den const-Zeiger aus der Klasse und mache ihn in main lokal.

- Ich mache den Zeiger nicht const und verschiebe ihn lokal.

-Wenn ich den Rückgabetyp void mache und ihm keine Parameter gebe

Ich glaube, Microsoft Visual Studio kann Zeiger überhaupt nicht inline-funktionieren ...

    
Christian Veenman 09.05.2013, 13:19
quelle

4 Antworten

2

Das Problem liegt nicht beim Inlining, was der Compiler bei jeder Gelegenheit tut. Das Problem ist, dass Visual C ++ nicht zu erkennen scheint, dass die Zeigervariable tatsächlich eine Kompilierzeitkonstante ist.

Testfall:

%Vor%

Die Funktionen sind in mehrere Kompilierungseinheiten unterteilt, um das Inlining besser steuern zu können. Insbesondere möchte ich nicht show_int inlined, da es den Assembly-Code unordentlich macht.

Der erste Anflug von Problemen ist, dass der gültige Code (die kommentierte Zeile) von Visual C ++ zurückgewiesen wird. G ++ hat kein Problem damit , aber Visual C ++ beschwert sich über "erwarteten konstanten Ausdruck der Kompilierungszeit". Dies ist tatsächlich ein guter Prädiktor für zukünftiges Verhalten.

Bei aktivierter Optimierung und normaler Kompilierungssemantik (keine querschnittsübergreifende Inlining) generiert der Compiler:

%Vor%

Es besteht bereits ein großer Unterschied zwischen sum_ptr und nicht sum_ptr . Anweisungen, die sum_ptr verwenden, generieren einen indirekten Funktionsaufruf call DWORD PTR _sum_ptr , während alle anderen Anweisungen einen direkten Funktionsaufruf call _sum generieren, selbst wenn der Quellcode einen Funktionszeiger verwendet hat.

Wenn wir nun inlining aktivieren, indem wir function_pointer_resolution.cpp und sum.cpp mit /GL kompilieren und mit /LTCG verknüpfen, finden wir heraus, dass der Compiler alle direkten Aufrufe einleitet. Indirekte Anrufe bleiben unverändert.

%Vor%

Bottom-line: Ja, der Compiler führt Inline-Aufrufe über einen Kompilierzeitkonstantenfunktionszeiger aus, solange dieser Funktionszeiger nicht aus einer Variablen gelesen wird. Diese Verwendung eines Funktionszeigers wurde optimiert:

%Vor%

aber das hat nicht:

%Vor%

Alle Tests werden mit Visual C ++ 2010 Service Pack 1 ausgeführt, kompiliert für x86, gehostet auf x64.

  

Microsoft (R) 32-Bit-C / C ++ -optimierender Compiler Version 16.00.40219.01 für 80x86

    
Ben Voigt 09.05.2013, 22:49
quelle
1

Sie können __forceinline ausprobieren. Niemand wird Ihnen sagen können, warum es nicht inline ist. Der gesunde Menschenverstand sagt mir, dass es jedoch sein sollte. / O2 sollte Code-Geschwindigkeit über Code-Größe (Inlining) bevorzugen ... Seltsam.

    
RandyGaul 09.05.2013 16:33
quelle
1

Ich denke, dass Sie in dieser Schlussfolgerung recht haben: "... kann keine Inlinefunktionszeiger überhaupt".

Dieses sehr einfache Beispiel unterbricht auch die Optimierung:

%Vor%

Ihr Beispiel ist für den Compiler noch komplexer, daher ist es nicht überraschend.

    
qehgt 09.05.2013 20:05
quelle
1

Dies ist keine echte Antwort, sondern eine "vielleicht Workaround": STL von Microsoft hat einmal erwähnt, dass lambdas leichter inlineable als f ptrs sein können, also könnten Sie das versuchen.

Wie eine Kleinigkeit erwähnt Bjarne oft, dass Sorte ist schneller als qsort, weil qsort Funktion ptr nimmt, aber wie andere Leute bemerkt haben gcc hat keine Probleme, sie zu inlining ... also vielleicht sollte Bjarne versuchen gcc: P

    
NoSenseEtAl 24.02.2014 18:04
quelle

Tags und Links