“Olası” ve “olası olmayan” makroların ne kadar kullanımı çok fazla?


12

Genellikle olarak bilinen likelyve unlikelymakrolar derleyiciye ifgenellikle bir girilip atlanmayacağını belirler. Bunu kullanmak bazı (oldukça küçük) performans iyileştirmeleriyle sonuçlanır.

Onları son zamanlarda kullanmaya başladım ve bu tür ipuçlarının ne sıklıkta kullanılması gerektiğinden emin değilim. Şu anda ifgenellikle olarak işaretlenmiş hata denetimi s ile kullanıyorum unlikely. Örneğin:

mem = malloc(size);
if (unlikely(mem == NULL))
  goto exit_no_mem;

Tamam görünüyor, ancak hata kontrolü ifoldukça sık ve sonuçta adı geçen makroların kullanımı.

Benim sorum şu, her hata kontrolünde çok fazla likelyve unlikelymakro var ifmı?

Biz oradayken, başka hangi yerlerde sıkça kullanılıyorlar?


Şu anki kullanımımda, gerçek zamanlı alt sistemden soyutlama yapan bir kütüphanede bulunuyor, bu nedenle programlar RTAI, QNX ve diğerleri arasında taşınabilir hale gelecekti. Bununla birlikte, işlevlerin çoğu oldukça küçüktür ve doğrudan bir veya iki başka işlevi çağırır. Birçoğu bile static inlineişlevlerdir.

Yani, her şeyden önce, profil oluşturabileceğim bir uygulama değil. Bağımsız bir uygulama değil, bir kütüphane olduğu için "şişe boyunlarını tanımlamak" mantıklı değildir.

İkincisi, sanki "Bunun pek olası olmadığını biliyorum, derleyiciye de söyleyebilirim" gibi. Aktif olarak optimize etmeye çalışmıyorum if.


7
bana optimizasyon mikro reeks ...
cırcır ucube

2
Uygulama kodu için, yalnızca profilleme bu kodun sıcak bir yolda kullanıldığını gösterdiğinde onları eklerdim.
CodesInChaos


@james, sadece söyler likelyve unlikelyvar olur ve ne yaparlar. Onları ne zaman ve nerede kullanmanın en iyisi olduğunu önerecek hiçbir şey bulamadım.
Shahbaz

@Shahbaz "Eğer durum sıklıkla yanlışsa, yürütme doğrusal değildir. Ortada, sadece ön getirme nedeniyle L1i'yi kirletmeyen büyük bir kullanılmayan kod yığını vardır. dal tahmini yanlış koşullu ifade çok verimsiz olabilir. " Yani, ihtiyacınız olan talimatların L1i önbelleğinde olduğundan emin olmak istediğiniz sıkı döngüler
James

Yanıtlar:


12

Kodunuzu bununla kirletmeye istekli olduğunuz performansa mı ihtiyacınız var? Küçük bir optimizasyon.

  • Kod sıkı bir döngüde çalışıyor mu?
  • Uygulamanızda performans sorunları var mı?
  • Uygulamanızı profillendirdiniz ve bu özel döngünün çok fazla CPU zamanına mal olduğunu belirlediniz mi?

yesYukarıdakilerin tümüne cevap veremediğiniz sürece , bunun gibi şeylerle uğraşmayın.

Düzenleme: düzenlemeye yanıt olarak. Profil veremeseniz bile, genellikle etkin noktaları tahmin edebilirsiniz. Herkes tarafından çağrılan bir bellek ayırma işlevi iyi bir adaydır, çünkü özellikle tüm kütüphanede çalışmak için makronun yalnızca tek bir kullanımını gerektirir.


1
Sadece net olmak gerekirse, sana oy vermedim. Ancak cevabınız sorumu gerçekten cevaplamıyor. (un)likelyMakronun nadiren kullanıldığını ve yalnızca son derece performans açısından kritik kodda olduğunu söylemeye mi çalışıyorsunuz ? Onu sık sık kullanmak "kötü uygulama" mu, yoksa sadece "gereksiz" mi?
Shahbaz

@Shahbaz Kodu daha az okunabilir yapar ve performans optimizasyonu önemsiz kazançtan önemsiz kayba kadar değişebilir. İkincisi, olasılıkla ilgili varsayım, kodun diğer bölümlerinde daha sonra yapılacak bir değişiklik nedeniyle yanlış veya yanlış olarak değiştiğinde. Gerekmedikçe asla kullanılmamalıdır.
Peter

3
@Peter: Sözdizimi çok kötü olmasa da, neyin olası veya neyin olası olduğuna dair gösterimler kod okuyan insanlara yararlı bilgiler sağlayabilir . Örneğin, gören if (likely(x==2 || x==3)) doOneThing(); else switch(x) { ... }ve programcının if2 ve 3 değerleri için bir kullanmasının yalnızca C'nin iki caseetiketi tek bir işleyici ile ilişkilendirebileceğini bilmemesinin bir sonucu olmadığını değerlendirebilir .
supercat

Kimse kritik bir nokta olduğunu düşündüğümü söylemedi. Bu sadece "olası olmayan" yolun daha az gerçekleşmesi değil, hızda hiç umursamadığınız o yolda koşullandırılmış olabilir . Örneğin, bir çevre birimi yanıt vermiyor, bu yüzden sıfırlamanız ve yine de uyumanız gerekiyor.
Benjamin Lindqvist

2

X86 / x64 için yazıyorsanız (ve 20 yaşındaki CPU'ları kullanmıyorsanız), __builtin_expect () kullanımından elde edilen performans artışı varsa ihmal edilebilir olacaktır. Bunun nedeni, modern x86 / x64 CPU'ların (Atom'dan% 100 emin değilim) dinamik dal tahminine sahip olmalarıdır, bu nedenle CPU daha sık alınan dal hakkında "öğrenir". Elbette, bu bilgi sadece sınırlı sayıda dal için saklanabilir, ancak sadece iki durum mümkündür. (A) "sık kullanılan" bir dalsa, programınız bu dinamik dal tahmininden yararlanır ve (b) "nadir" dal ise, yanlış tahminlerden dolayı herhangi bir gerçekçi performans görmezsiniz. bu tür nadir dallar (dalda yanlış tahminin 20 CPU döngüsü mavi ayda bir kez gerçekleşirse ÇOK kötü değildir).

Not: Bu, modern x86 / x64'de şube yanlış tahmininin öneminin düştüğü anlamına gelmez: 50-50 atlama-nojump şansı olan herhangi bir şube hala bir cezaya neden olacaktır (IIRC 10-20 CPU döngüleri), bu nedenle iç döngüler dallarında yine de kaçınılmalıdır. __Builtin_expect () 'in x86 / x64 üzerindeki önemi, çoğunlukla dinamik dal tahmini nedeniyle azalmıştır (IIRC, yaklaşık 10-15 yıl önce).

NB2: x86 / x64, YMMV dışındaki diğer platformlar için.


Derleyici, cpu'nun hangi dalda daha az olası olacağını biliyor. Ve bunun aslında olası olmayan biri olmasını ayarlayabilir. Ancak derleyici muhtemelen bu örüntüyü unlikely-notasyonsuz biliyordur.
Deduplicator

@Deduplicator: Dinamik dal tahminiyle derleyici, CPU'nun koddaki bu noktadan önceki çalıştırmalara dayanarak çalışma zamanında hesapladığı için hangi dalın daha olası olduğunu bilmiyor.
Hata Yok Tavşan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.