Giriş: Re-evaluating Function Call Overhead

C programlamada, her işlev çağrı eki getirir: derlemek, yığın üzerinde tartışma yapmak zorundadır (veya kayıtlarda onları geçmek), fonksiyon vücuduna atlamak, kodu uygulamak ve sonra geri dönmek.. küçük, sık sık sık kullanılan fonksiyonlar için, bu üst düzey bir zaman, özellikle de performans-kritik döngüler veya derinden neyin kurtarılmasına karar verebilir. Modern derleyiciler agresif bir şekilde optimize edilmelidir, ancak programcı uçabilir.

Inline Functions Arkasındaki Mechanism

Bir inline işlevi, C99 ve daha sonra standartlarda ilan edilir; bu, derleyicinin ayrıntılı olarak tanımlandığı bir öneridir.Bir başlık dosyasında, çoğaltma veya bağlantılama hataları olmadan, düşük olan fonksiyonlar için göz ardı edilebilir.In C99 ve daha sonraki standartlarda, bu genellikle bir yerde ulaşılamaz:2|Dönemli bir açıklama ile elde edilir.

  • [FONT:0]Static inline:[Dönetici] işlevin içsel bağlantıya sahip olması; her çeviri birimi kendi kopyasını alır. Bu, üst düzeylerde tanımlanan küçük yardımcı işlevlerin en güvenli ve en taşınabilir yaklaşımıdır.
  • [FONT:0)Extern inline (C99): İnline tanımı, vücutları ayrı ayrı olarak bulunmalıdır (genellikle bir .c dosyasında).
  • [FONT:0] Statik veya extern olmadan Inline:) C99'da, bu dışsal olarak benzer; C11'de, dış tanımlar yalnızca fonksiyon sabit değilse gereklidir.

[FONT:0)Key bilgi:[Dönetici] Inlining ücretsiz bir öğle yemeği değildir. derleyici, maliyet-benefit ticaretini analiz eder: her çağrı sitesinde bir işlev vücut eklemek kod boyutunu arttırır (kop bloat) ve böylece önbellekliliği azaltabilir.

Inline Functions Excel: Cases ve En İyi Uygulamaları Kullanın

Küçük Matematik Operasyonları

Temel arithmetici performans gösteren fonksiyonlar - bir meydan okuma, bir değere kilitlemek veya bir işaret test etmek gibi - asal adaylardır.Bir işlev çağrısının üst kısmı genellikle operasyondan daha büyükdir. Örneğin:

static inline int clamp(int value, int low, int high) {
 return (value < low) ? low : (value > high) ? high : value;
}

Data Structures'taki Accessor ve Mutator Fonksiyonlar

C'deki nesne odaklı modeller genellikle toplayıcıları ve setters'leri enkapsulate verileri kullanmak için kullanılır.Inlining olmadan, bu önemsiz fonksiyonlar gereksiz yere ekliyor:

typedef struct {
 int x, y;
} Point;

static inline int point_get_x(const Point *p) {
 return p->x;
}

static inline void point_set_x(Point *p, int x) {
 p->x = x;
}

Gömülü Sistemler ve Gerçek Zaman Kodu

Sınırlı yığın uzay ve determinist zamanlama gereksinimleri olan ortamlarda, doğrusal fonksiyonlar, hem geç kalmış hem de hafıza kullanımını azaltmak için ihtiyaç ortadan kaldırır. Ancak, kod büyüklüğü hafızaya dönük mikro kontroller üzerinde dikkatle takip edilmelidir.

[FONT=0)[Dönemli değil.

  • [FONT=0)Large işlevleri:[Dönetici:[Dönetici:0) Birden çok arama sitelerinde 100+ çizgi işlevinin olması, önbellek baskı nedeniyle ikili ve muhtemelen degrad performansına engel olacaktır.
  • [FONT:0)Recursive işlevleri:[Dönetici:[Dönetici:0)Recursive işlevleri:[Dönetici:[Dönetici:0)[Dönetici:[Dönetici:0)Recursion tamamen inlined edilemez (sa, derleyici birkaç seviye kayıt olmayabilir).
  • [FONT:0]Çalışanlar ile:) Büyük bir döngü içeren bir işlev önemli fayda sağlamayabilir.
  • [FONT:0)Rarely işlevleri denir:[Dönetici:[Dönetici:0)[Dönetici:[Dönetici:0)))

Inline Functions Versus Macros: A detailed Karşılaştırma

C programcılar standart olduğundan önce makrolar ([Dönemli) "inlining" elde etmek için kullanılır - ancak makrolar metin alt kurumlardır, işlevleri değil.

  • [FONT=0)Type security:[Dönetici:[Dönetici:) Macros not types.The infamousENFLT:11), makro, birçok kez iddiaya göre, doğru ifadelerle kullanıldığında tehlikeli yan etkilere yol açar.
  • [FONT:0)Debugging:[Dönetici:[Dönetici: 1 ) Makrolar önceden işleme sırasında kaybolur; debuggers onlara adım atamaz.
  • [FONT=0]Compound ifadeleri:[[Dönemli) Çok devletli makrolar çirkin çalışma alanları gerektirir (örneğin, [[Dönemli: 9).
  • [FONT:0] Kompiyon çarpışmaları:[Dönetici:[Dönetici:0) Makro genişlemeler yerel değişkenlere müdahale edebilir.

Inline işlevleri tüm bu sorunları aşmaktadır: tip kontrol, kapsamı ve yan etkiler-güvenli tartışma değerlendirmesi ile gerçek işlevleridir. Düzenli tip sisteme katılırlar ve makroların tek teorik avantajı, [[0tip-generic[FLT] işlemleri için kullanılabilir olmasıdır - ancak C11FLT::14 ve C23:03T:15

[FONT:0)Dönetici:[Dönetici: · 1) · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · · ·

Pratik örnekler: Eylemde Inline Functions in Action

Örnek 1: Square (Already Provided)

static inline int square(int x) {
 return x * x;
}

Kombinasyon muhtemelen hiçbir şekilde talimat vermeyecektir; kod her çağrı sitesinde sadece [[ŞUYGÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜŞÜNÜ

Örnek 2: Bir Karakterin Digit

static inline int is_digit(char c) {
 return c >= '0' && c <= '9';
}

Örnek 3: Hızlı Min/Max (Avoiding Macros)

static inline int imax(int a, int b) {
 return (a > b) ? a : b;
}

Makro sürümden farklı olarak, bu, AMAFLT:21'i ve [[Dönetici:2|Dönemli ve s.

Örnek 4: Bit Operasyonları (Unions veya Byte Swapping)

static inline uint16_t swap_bytes(uint16_t x) {
 return (x << 8) | (x >> 8);
}

Bu, ARM'de bir tek bir İLDİYEN KAYNAK veya lineer olduğunda x86'da bir rotasyona dönüşür.

Compiler Optimizasyonlar ve Inline Keyword

[[Theurs: TherFLT:25} anahtar kelime sadece bir derleme kararında bir faktördür. Çoğu derleyicinin kontrol agresifliği olan komut satırı bayrakları vardır:

  • [FONT=0)GCC/Clang:[Dönetici:[Dönetici: {0)) {0}[0|Kutsal olmayan özel bir işlevi zorlamak, [[Döneticiler, kullanımlar için daha agresif hale getirmek için.
  • [FONT:0)MSVC:[Dönetici:[Dönetici:0)[[FONT:0))[[[FONT:0)))[[[FONT:0)))))))))[[[[FONT=FONT=0))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))

GCC özelliği ile örnek:

static inline __attribute__((always_inline)) int triple(int x) {
 return x * 3;
}

Performans-kahkalama kodu için, üretilen montajı (örneğin GCC'nin 03.03.2014 veya [[Dönetici) kontrol etmek tavsiye edilir. Modern derleyiciler yüksek optimizasyon seviyelerinde işaretleyemezler ve tersine aşırı kod büyümesine sebep olan işlevleri görmezden gelebilir.

Potansiyel Pitfalls: Code Bloat ve İkili Boyut

Birçok yerde kullanılan bir işlev çağrısının her çağrısını yapmak, metin segmentinin boyutunu önemli ölçüde artırabilir.Bu özellikle sorunlu:

  • [FONT:0)Libraries:[[Döncülerdeki Inline işlevleri onları içeren her çeviri birimine genişletilir, potansiyel olarak kod boyutunu çoğaltır.
  • [FONT:0)Embedded sistemleri: [Dönetici: Flash ve RAM sınırlı. 1000 yerde kullanılan 10bayt fonksiyonu neredeyse 10 koda sahiptir.
  • [FONT=0)Instruction önbellek:[Dönetici:[Dönetici:0) Büyük kod daha önbelleklilere neden olabilir, tüm programı yavaşlatır.

Kod bloatını azaltmak için, sadece gerçekten küçük fonksiyonlar için (tipik olarak 1-5 ifade) kullanmak için kod bloat kullanın. hem yürütme süresi hem de ikili boyutu belirlemek için profiller kullanın.

Inline Functions Across C Standards

[FONT=38] Anahtar kelimeler [[C99[FONTT:0) ve daha fazla açıklanmış olan (Dönetici) ile aynı ayrımı yerine getiriyor.[FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=TRNT=FONT=FONT=FONT=FONT=FONT=FONT=TRNT=FONT=TRNT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=FONT=I=FONT=FONT=FONT=FONT=FONT=FONT=

Pre-C99 derleyiciyi desteklemeniz gerekir (bu giderek nadirdir), makrolara veya dış başlık-yalnızca uygulamaları geri almanız gerekir. Aksi takdirde, alışılmış ve güvenli bir alternatif olarak TAY:40'u kucaklayın.

Sonuç: Performans Mühendisi'nin Toolkit'teki Stratejik Bir Araç

Inline işlevleri, C dilinin olgun, iyi tanımlanmış bir özelliğidir, çünkü judicious olarak uygulandığında, fonksiyon çağrılarını ortadan kaldırarak ölçülebilir hız iyileştirmelerini sağlayabilir ve devre dışı optimizasyonları sağlar. - düşük seviyedeki programlamada nadir bir kombinasyondur.

Daha fazla okuma için, [[0)GCC dokümanı doğrusal fonksiyonlarda () ve [[Dönetici giriş için [[2|DÜye Olmayanlar için Giriş:0)[DÜye Olmayanlar İçindeki Performans Analizi, [[Döneticiler İçin Tıklayınız.