2011-09-18 19 views
13

Bazı işlevlerim var, her biri yaklaşık iki basit kod satırı ve bunlar birbirini şöyle çağırıyorlar:çağrıları B çağrıları C çağrıları D ... K. (Yani temelde uzun bir dizi kısa işlev çağrısı.) Derleyiciler genellikle bu işlevleri çağırmak için çağrı ağacına ne kadar girer?Derleyiciler satır içi işlevleri ne kadar derin?

+0

Montajı basitçe test edebilir ve bakabilirsin! Derleyici belgeleriniz, satır içi derinliğin nasıl belirtileceğini size söylemelidir; Varsayılan olarak GCC için 50 gibi bir şey olduğunu düşünüyorum. –

+2

Bunun derleyici özel olması gerektiğine inanıyorum ve derleyicinizin hiçbir bilgisini paylaşmıyorsunuz. –

+1

MSVC altında, belirli durumlarda (örneğin, özyinelemeli gibi) sorunlarla karşılaştığımda '#pragma inline_depth' (http://msdn.microsoft.com/en-us/library/cx053bca.aspx) kullanarak kısmi bir kontrole sahipsiniz. mümkünse, ancak, hiç bir zaman işe yaramadı, manüel olarak yapılıyordu) – Necrolis

cevap

12

Soru anlamlı değil.

Eğer inlining düşünürseniz, ve sonuçları, bunu fark edeceksiniz:

  • optimizer daha fazla bağlam Exposes (bütün kayıt kaydetme/çerçeve ayarlı) bir işlev çağrısını önler (diğer şeyler arasında talimat önbellek ve yürütülebilir boyutu, şişkinlik ölü mağazalar, ölü kod, ortak alt ifade elimintation ...)
  • çoğaltır kodu()

karar Satır içi olsun ya da olmasın, derleyici, yaratılan potansiyel bloat ve beklenen hız kazancı arasında bir dengeleme eylemi gerçekleştirir. Bu dengeleme eylemi seçenekler tarafından etkilenir: gcc için -O3 hızını optimize etmek anlamına gelirken, -Oz boyutu en iyi tersi davranışlara sahipken, satır içi için en iyi duruma getirme anlamına gelir! Bu nedenle, önemli olan "yuvalama seviyesi" değil, talimat sayısıdır (büyük olasılıkla hepsi eşit oluşturulmamış olarak ağırlıklandırılır).

int foo(int a, int b) { return foo(a, b, 3); } 

bakış inlining noktasından temel olarak "saydam" dir:

Bu basit yönlendirme fonksiyonu anlamına gelir.

Diğer taraftan, yüz kod satırı sayan bir işlevin satır içi olmaması olası değildir. Bunun dışında sadece bir kez çağrılan bir static serbest fonksiyonu, bu durumda herhangi bir çoğaltma oluşturmayacağından, sistematik olarak sıralı olarak belirtilmiştir. Bu iki örneğe göre

biz sezgisel nasıl davrandığını önsezi olsun: var

  • az talimatlar işlevini
  • inlining için daha iyi, denir az sıklıkta
  • inling için daha iyi Bundan sonra

, onlar parametreleri onlar -finline-limit bayrak tresh "yükseltmek" olarak tek bir yolu etkilemek için ayarlayabilirsiniz veya kuvvetle inling ima __force_inline olarak başka (MSVC, gcc geçilmemelidir talimat sayımı teğet günü, vs ...)


eski: yaklaşık kısmi satır içi uygulaması biliyoruz?4.6'da gcc'de tanıtıldı. Adından da anlaşılacağı gibi fikir, bir işlevi kısmen satır içi tutmaktır. Çoğunlukla, işlev "korunur" olduğunda bir işlev çağrısının genel giderlerinden kaçınmak ve (bazı durumlarda) hemen hemen geri dönebilir. Örneğin

:

void foo(Bar* x) { 
    if (not x) { return; } // null pointer, pfff! 

    // ... BIG BLOC OF STATEMENTS ... 
} 

void bar(Bar* x) { 
    // DO 1 
    foo(x); 
    // DO 2 
} 

olarak "optimize" alabilir:

Tabii
void [email protected](Bar* x) { 
    // ... BIG BLOC OF STATEMENTS ... 
} 

void bar(Bar* x) { 
    // DO 1 
    if (x) { [email protected](x); } 
    // DO 2 
} 

kez daha inlining için sezgisel uygulamak, ancak daha discriminately geçerlidir!


Ve WPO (Tüm Program Optimizasyonu) ya da LTO (Bağlantı Zaman Optimizasyonu) kullanmadığınız sürece kendi tanım aynı TU (Çeviri Birimi) ise nihayet, işlevleri yalnızca satır içine yerleştirilmiş olabilir çağrı sitesinde söyledi.

+0

Genellikle bunu yapmıyorum, ama kabul edilen cevabı değiştirmem gerektiğini düşünüyorum. :) Kısmi satır içi ve ne kadar çağrı sayısına bağlı olarak inlining hakkında bilmiyordum. Detaylar için teşekkürler. –

7

Derleyicilerin 5'den fazla işlevi derinlemesine satır içi olarak gördüm. Ama bir noktada, temel olarak derleyicinin yaptığı uzay verimliliği ticaretine dönüşür. Bu derlemede her derleyici farklıdır. Visual Studio, inlining ile çok muhafazakar. GCC (altında -O3) ve Intel Derleyici inline satır içi ...

+0

gcc 'de IIRC, satır içi fonksiyona (yani gerçekte ne kadar uzun olduğu) ilişkin yaklaşık "talimat sayısı" na bağlıdır; Yuvalama seviyesi, dokümanlardaki ('-finline-limit 've arkadaşları) okuduğumdan, 10'luk fonksiyonun 5 + yuvalanmış 5 ile aynı şekilde iç içe geçeceği anlamında rol oynamaz. – eudoxos

+1

Eğer fonksiyonlar çağrılırsa sadece bir kez satır içi önlemek için hiçbir neden yoktur. GCC, profil geri bildirimi gerektiğini söylerse, agresif bir şekilde satır içi olarak da geçerli olacaktır. –

+3

@Zan Lynx: Bu çoğunlukla doğru. Satır içi olmamasının daha iyi olduğu bazı durumlar vardır. İşlev, performans açısından kritik bir döngüde ise ve nadiren çağrılırsa (bir yakalama işleyicisi gibi), döngü küçüklüğünün kod boyutunu korumak için satır içi olarak değil. (bazen uzun atlayışlar yerine kısa atlayışlar kullanmanıza izin verir) – Mysticial