2010-03-16 8 views
6

Ich benutze gcc mit der -finline-Funktionen Optimierung für Release-Builds. Um Code Bloat zu bekämpfen, weil ich an einem eingebetteten System arbeite, möchte ich sagen, dass bestimmte Funktionen nicht inline sind. Der offensichtliche Weg, dies zu tun, wäre durch Funktionsattribute, dh Attribut (Noinline). Das Problem ist, das scheint nicht zu funktionieren, wenn ich die Global-Finline-Funktionen-Optimierung, die Teil der -O3-Schalter ist, einschalten.gcc -finline-Funktionen Verhalten?

Es hat auch etwas damit zu tun zu sein, da eine nicht vorgestanzte Version der gleichen Funktion nicht inline wird, was wie erwartet ist.

Hat jemand eine Idee, wie man das Inlining steuert, wenn dieser globale Schalter eingeschaltet ist?

Hier ist der Code:

#include <cstdlib> 
#include <iostream> 

using namespace std; 

class Base 
{ 
public: 

    template<typename _Type_> 
    static _Type_ fooT(_Type_ x, _Type_ y) __attribute__ ((noinline)); 
}; 

template<typename _Type_> 
_Type_ Base::fooT(_Type_ x, _Type_ y) 
{ 
    asm(""); 
    return x + y; 
} 


int main(int argc, char *argv[]) 
{ 
    int test = Base::fooT(1, 2); 
    printf("test = %d\n", test); 

    system("PAUSE"); 
    return EXIT_SUCCESS; 
} 
+1

Nicht verwandt, aber Bezeichner, die mit einem Unterstrich gefolgt von einem Großbuchstaben beginnen, sind für den Compiler reserviert. – GManNickG

+0

Sollte das Attribut __ ((noinline)) nicht an die Definition angehängt werden? – jpalecek

+0

@jpalecek: Nein, das ist ein Kompilierungsfehler – user176168

Antwort

4

Die docs for GCC's noinline sagen:

Diese Funktion Attribut eine Funktion verhindert, dass für inlining betrachtet. Wenn die Funktion keine Nebeneffekte hat, gibt es andere Optimierungen als Inlining, die dazu führen, dass Funktionsaufrufe weg optimiert werden, obwohl der Funktionsaufruf aktiv ist. Um solche Anrufe von halten wird wegoptimiert, setzen

 asm (""); 

(siehe Erweiterte Asm) in der aufgerufenen Funktion als besondere Nebenwirkung zu dienen

Ich denke, dass das, was Sie passiert sein könnte ist, dass, da die Base::fooT<> Funktion keine Nebenwirkungen hat, GCC die oben genannten unspezifizierten anderen Optimierungen aufruft.

+0

Entschuldigung für die lange Verzögerung bei der Antwort! Nö leider gcc noch drin, ich hatte das schon mal probiert. Ich benutze 4.1.1 kennt jemand einen Bug in Bezug auf diese? Danke für die Antwort, aber es scheint nicht, dass es eine Menge Wissen über dieses Thema gibt ... – user176168

1

Versuchen Sie das noinline Attribut nach dem static und vor der Definition setzen wie so:

template<typename _Type_> 
    static __attribute__ ((noinline)) _Type_ fooT(_Type_ x, _Type_ y); 

Das ist für mich gearbeitet und scheint auch für andere zu arbeiten, finden Sie unter: How can I tell gcc not to inline a function?

Aus irgendeinem Grund es doesn Arbeiten Sie nicht das Attribut noinline nach der Funktion oder indem Sie die in den Funktionskörper setzen, was die gcc Dokumentation sagt.

1

Kleiner alter Thread aber lohnt sich zu beantworten. Wenn nichts weiter für Sie funktioniert, gibt es immer eine einfache Problemumgehung. Sie müssen die Implementierung aus der Übersetzungseinheit ausblenden, in der Sie eine solche Methode verwenden möchten, indem Sie sie in eine andere cpp-Datei einfügen.

EDIT

In GCC> = 4.5 gibt es ein Attribut noclone, die die Funktion von spezialisierten noinline in Art und Weise ersetzen.