Come posso dire che gcc non in linea una funzione?

Dire che ho questa piccola funzione in un file di origine

static void foo() {}

e ho costruito una versione ottimizzata del mio binario ma non voglio questa funzione inline (per le finalità di ottimizzazione). c’è una macro che mi permette di aggiungere un codice sorgente per prevenire l’inlining?

  • Grazie per questa domanda! Ero profilatura con esso quando una funzione non si fece vedere, le risposte qui risolto questo.
InformationsquelleAutor vehomzzz | 2009-09-24

 

8 Replies
  1. 134

    Si desidera che il gccspecifiche noinline attributo.

    Questa funzione impedisce un attributo
    funzione da essere considerato per
    inline. Se la funzione non
    hanno effetti collaterali, ci sono
    ottimizzazioni altri inlining che
    cause chiamate di funzione per essere ottimizzato
    di distanza, anche se la chiamata di funzione
    live. Per mantenere tali chiamate da essere
    ottimizzato di distanza, mettere
    asm ("");

    Usarlo come questo:

    void __attribute__ ((noinline)) foo() 
    {
      ...
    }
    • Utilizzando gcc 4.4.3 su Arch Linux, ho un errore di sintassi con l’attributo inserito come sopra. Funziona correttamente quando precede la funzione (ad esempio, attributo ((noinline)) void foo() {})
    • Arduino anche voluto collocato prima della funzione.
    • Editato per correggere la sintassi di attributo.
    • L’asm(“”) costruire in realtà è abbastanza cross-platform e ha ottenuto il lavoro fatto. L’ho fatto per Linux x86 e non causare un problema di compilazione su architettura PowerPC AIX. Grazie per questo utile suggerimento!
    • Utilizzando gcc 6.2.1 su Arch Linux, nessun problema.
    • Solo per curiosità, Non utilizzando la parola chiave extern Per e,g extern void foo(); ha lo stesso effetto come noinline attributo.
    • L’approccio che richiede modifiche al codice ovunque non può essere ragionevolmente considerata una risposta accettabile.
    • Io pensa che e ‘ un altro esempio del compilatore di attivazione di un programma di lavoro in un non-lavoro. Forse si può supplicare il vostro caso al GCC. (Io sono felice c’era una soluzione a Etichette in GCC assembly inline, dove l’ottimizzatore ripetuto nostro inline ASM e ha causato più simboli con lo stesso nome).

  2. 28

    GCC è un parametro denominato

    -fno-inline-small-functions

    In modo da utilizzare che in caso di richiamo di gcc. Ma l’effetto collaterale è che tutte le altre piccole funzioni anche non allineate.

    • Non lavoro al compilatore di livello. Stava usando gcc 5.2.1 20150902 (Red Hat 5.2.1-2)
    • Corrente GCC 6.4 è rotto, o questo e più semplice -fno-inline non funzionano affatto. gdb ancora entra metodi di passo. C’è qualcosa di rotto, e il dubbio mi è gdb.
    • Per spegnere inline ottimizzazione per tutti, non solo per una specifica funzione.
  3. 21

    Un portatile modo per farlo è quello di chiamare la funzione tramite un puntatore:

    void (*foo_ptr)() = foo;
    foo_ptr();

    Anche se questo produce diverse istruzioni di branch, che non può essere il tuo obiettivo. Che porta fino a un buon punto: che cosa è qui il tuo obiettivo?

    • Non sempre funziona. Alcuni di essi sono ancora in grado di ottimizzare la…
    • Se il puntatore è definito in ambito file, e non statico, dovrebbe funzionare dato che il compilatore quindi non posso assumere ha il suo valore iniziale al momento dell’uso. Se si tratta di un locale (come mostrato) è quasi certamente trattati come i foo(). (“In questo decennio”, ha aggiunto, guardando le date)
  4. 13

    Nel caso In cui si ottiene un errore del compilatore __attribute__((noinline)), si può solo provare:

    noinline int func(int arg)
    {
        ....
    }
    • Ho un errore: noinline non il nome di un tipo.
  5. 10

    So che la domanda è su GCC, ma ho pensato che potrebbe essere utile
    po ‘ di informazioni su altri compilatori compilatori.

    Di GCC
    noinline
    funzione di attributo è molto popolare con altri compilatori. Si
    è supportato da almeno:

    • Clang (controllare con __has_attribute(noinline))
    • Intel C/C++ Compiler (la loro documentazione è terribile, ma io sono
      certo che funziona su 16.0+)
    • Oracle Solaris Studio almeno 12.2
    • BRACCIO Compilatore C/C++ almeno 4.1
    • IBM XL C/C++ almeno 10.1
    • TI 8.0+ (o 7.3+ con –gcc, che definirà __TI_GNU_ATTRIBUTE_SUPPORT__)

    Inoltre, supporta MSVC
    __declspec(noinline)
    a Visual Studio 7.1. Intel probabilmente supporta troppo (cercano di
    essere compatibile sia con GCC e MSVC), ma non ho preso la briga di
    verificare che. La sintassi è praticamente lo stesso:

    __declspec(noinline)
    static void foo(void) { }

    IGP 10.2+ (e probabilmente il vecchio) supporta un noinline pragma che
    si applica alla funzione successiva:

    #pragma noinline
    static void foo(void) { }

    TI 6.0+ supporta un
    FUNC_CANNOT_INLINE
    pragma che (fastidiosamente) funziona in modo diverso in C e C++. In C++, è simile a IGP dell’:

    #pragma FUNC_CANNOT_INLINE;
    static void foo(void) { }

    In C, tuttavia, il nome della funzione è necessario:

    #pragma FUNC_CANNOT_INLINE(foo);
    static void foo(void) { }

    Cray 6.4+ (e forse anche prima) prende un simile approccio, che richiedono
    il nome della funzione:

    #pragma _CRI inline_never foo
    static void foo(void) { }

    Oracle Developer Studio, inoltre, supporta un pragma, che prende il
    il nome della funzione, tornando a almeno Forte Sviluppatore
    6
    ,
    ma nota che deve venire dopo la dichiarazione, anche recenti
    versioni:

    static void foo(void);
    #pragma no_inline(foo)

    A seconda di come dedicato sono, è possibile creare una macro che
    vorresti lavorare ovunque, ma si avrebbe bisogno di avere il nome della funzione
    così come la dichiarazione di argomenti.

    Se, OTOH, stai bene con qualcosa che funziona per la maggior parte delle persone,
    si può ottenere via con qualcosa che è un po ‘ di più esteticamente
    piacevole e non ha bisogno di ripetersi. Questo è l’approccio
    Ho preso per Hedley, dove il
    versione corrente di
    HEDLEY_NEVER_INLINE
    assomiglia a:

    #if \
      HEDLEY_GNUC_HAS_ATTRIBUTE(noinline,4,0,0) || \
      HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
      HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \
      HEDLEY_ARM_VERSION_CHECK(4,1,0) || \
      HEDLEY_IBM_VERSION_CHECK(10,1,0) || \
      HEDLEY_TI_VERSION_CHECK(8,0,0) || \
      (HEDLEY_TI_VERSION_CHECK(7,3,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__))
    #  define HEDLEY_NEVER_INLINE __attribute__((__noinline__))
    #elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
    #  define HEDLEY_NEVER_INLINE __declspec(noinline)
    #elif HEDLEY_PGI_VERSION_CHECK(10,2,0)
    #  define HEDLEY_NEVER_INLINE _Pragma("noinline")
    #elif HEDLEY_TI_VERSION_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
    #else
    #  define HEDLEY_NEVER_INLINE HEDLEY_INLINE
    #endif

    Se non si desidera utilizzare Hedley (si tratta di un singolo dominio pubblico /CC0
    intestazione) è possibile convertire il controllo della versione macro, senza troppo
    sforzo, ma più di quanto io sono disposto a mettere in ☺.

    • Grazie per il link al progetto @nemequ. Ho chiesto al nostro altri sviluppatori per valutare per il nostro uso. Abbiamo diverse architetture.
    • Sarei molto interessato a sapere cosa dicono, soprattutto se non sono interessati. E, naturalmente, ci sono io a rispondere alle domande (GitHub issue tracker, e-mail, qualsiasi cosa…).
  6. 9
    static __attribute__ ((noinline))  void foo()
    {
    
    }

    Questo è quello che ha funzionato per me.

  7. 7

    Utilizzare il noinline attributo:

    int func(int arg) __attribute__((noinline))
    {
    }

    Probabilmente si dovrebbe usare sia quando si dichiara la funzione per uso esterno e quando si scrive la funzione.

  8. 1

    Io lavoro con gcc 7.2. In particolare ho bisogno di una funzione non-allineate, perché doveva essere istanziato in una libreria. Ho provato il __attribute__((noinline)) risposta, così come il asm("") risposta. Nessuno ha risolto il problema.

    Infine, ho pensato che la definizione di una variabile statica all’interno della funzione di forzare il compilatore di allocare spazio per la variabile statica blocco, e per un problema di inizializzazione quando la funzione viene chiamata.

    Questo è una sorta di trucco sporco, ma funziona.

    • Si potrebbe definire la funzione inline void foo(void) { ... } in un header e dichiarare extern inline void foo(void); in una libreria di file di origine. A seguito di C99 semantica, il compilatore sarebbe consentito inline funzione, quando piace E di emettere il codice dell’oggetto in libreria. Vedere È “in linea” senza “statico” o “extern” mai utile in C99 ?.

Lascia un commento