Hoe kan ik gcc vertellen een functie niet inline te plaatsen?

Stel dat ik deze kleine functie in een bronbestand heb

static void foo() {}

en ik bouw een geoptimaliseerde versie van mijn binaire bestand, maar ik wil niet dat deze functie inline is (voor optimalisatiedoeleinden). is er een macro die ik in een broncode kan toevoegen om inlining te voorkomen?


Antwoord 1, autoriteit 100%

U wilt de gcc-specifieke noinlinekenmerk.

Dit functiekenmerk voorkomt a
functie niet in aanmerking komen
inlijnen. Als de functie niet
bijwerkingen hebben, zijn er
andere optimalisaties dan inline dat
zorgt ervoor dat functieaanroepen worden geoptimaliseerd
weg, hoewel de functieaanroep is
live. Om te voorkomen dat dergelijke oproepen worden
geoptimaliseerd weg, zet
asm ("");

Gebruik het als volgt:

void __attribute__ ((noinline)) foo() 
{
  ...
}

Antwoord 2, autoriteit 23%

GCC heeft een schakelaar genaamd

-fno-inline-small-functions

Gebruik dat dus bij het aanroepen van gcc. Maar het neveneffect is dat alle andere kleine functies ook niet-inline zijn.


Antwoord 3, autoriteit 15%

Ik weet dat de vraag over GCC gaat, maar ik dacht dat het misschien handig zou zijn om
heb ook wat informatie over compilers en andere compilers.

GCC’s
noinline
function attribuut is ook behoorlijk populair bij andere compilers. Het
wordt ondersteund door ten minste:

  • Clang (controleer met __has_attribute(noinline))
  • Intel C/C++ Compiler (hun documentatie is verschrikkelijk, maar ik ben
    zeker dat het werkt op 16.0+)
  • Oracle Solaris Studio terug naar minimaal 12.2
  • ARM C/C++ Compiler terug naar minimaal 4.1
  • IBM XL C/C++ terug naar minimaal 10.1
  • TI 8.0+ (of 7.3+ met –gcc, die __TI_GNU_ATTRIBUTE_SUPPORT__definieert)

Bovendien ondersteunt MSVC
__declspec(noinline)
terug naar Visual Studio 7.1. Intel ondersteunt het waarschijnlijk ook (ze proberen
compatibel zijn met zowel GCC als MSVC), maar ik heb niet de moeite genomen om
Verifieer dat. De syntaxis is in principe hetzelfde:

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

PGI 10.2+ (en waarschijnlijk ouder) ondersteunt een noinlinepragma dat
geldt voor de volgende functie:

#pragma noinline
static void foo(void) { }

TI 6.0+ ondersteunt a
FUNC_CANNOT_INLINE
pragma dat (vervelend) anders werkt in C en C++. In C++ is het vergelijkbaar met BGA’s:

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

In C is de functienaam echter vereist:

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

Cray 6.4+ (en mogelijk eerder) hanteert een vergelijkbare aanpak, waarbij:
de functienaam:

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

Oracle Developer Studio ondersteunt ook een pragma dat de
functienaam, teruggaand naar ten minste Forte Developer
6
,
maar merk op dat het nade aangifte moet komen, zelfs in recente
versies:

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

Afhankelijk van hoe gewijd je bent, zou je een macro kunnen maken die
zou overal werken, maar je zou de functienaam moeten hebben als
evenals de verklaring als argumenten.

Als, otoh, bent u in orde met iets dat gewoon voor de meeste mensen werkt,
Je kunt wegkomen met iets dat een beetje esthetisch is
aangenaam en hoeft niet te worden herhaald. Dat is de aanpak
Ik heb voor hedley , waar de
Huidige versie van
hedley_never_inline
eruit ziet:

#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_CHECK(6,0,0)
#  define HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;")
#else
#  define HEDLEY_NEVER_INLINE HEDLEY_INLINE
#endif

Als u Hedley niet wilt gebruiken (het is een enkel publiek domein / CC0
header) Je kunt de versie converteren met macro’s zonder te veel
inspanning, maar meer dan ik bereid ben om in ☺ te plaatsen.


4, Autoriteit 8%

Als u een compiler-fout voor __attribute__((noinline)), kunt u het gewoon proberen:

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

5, Autoriteit 7%

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

Dit is wat voor mij werkte.


6, Autoriteit 5%

Gebruik de noinlineattribuut :

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

U moet het waarschijnlijk gebruiken, zowel wanneer u de functie voor extern gebruik aangeeft en wanneer u de functie schrijft.


7

Ik werk met GCC 7.2. Ik had specifiek een functie nodig om niet-inline te zijn, omdat het in een bibliotheek moest worden geïnstantieerd. Ik heb de __attribute__((noinline))Antwoord geprobeerd, evenals de asm("")Antwoord. Geen van beide loste het probleem op.

Ten slotte, ik dacht dat het definiëren van een statische variabele in de functie de compiler zal dwingen de ruimte ervoor toe te wijzen in het statische variabele blok en om er een initialisatie voor te geven wanneer de functie voor het eerst wordt genoemd.

Dit is een soort vuile truc, maar het werkt.

Other episodes