Soru C ++ Performansını Anlamak için Kaynaklar? [kapalı]


C ++ performansının derinlemesine anlaşılmasına yardımcı olacak kaynakları (ideal olarak bir kitap) arıyorum. İşte biraz daha arka plan:

Çok yüksek verimlilik gereksinimleri ve / veya düşük gecikme gereksinimleri olan bir sunucu yazılımı yazarım. C ++ ile yazıyoruz; Bu zamanda tartışma konusu değil. İş arkadaşlarımın çoğu C ++ performansı hakkında daha iyi bir anlayışa sahip görünüyor. Daha iyi zihinsel modellere sahipler, bu yüzden belirli bir kod parçasının ne zaman zayıf bir şekilde performans göstereceğini anlayabilirler. Bu anlayıştan yoksun ve bu yüzden zihinsel modelimi geliştirmeye çalışıyorum.

Özellikle ilgileniyorum:

  • Önbellek efektlerini ve nesne yerleşimi nedeniyle önbellek mevkisini anlama kodumun performansını etkiler. Bu, ekibimin diğer üyeleri tarafından ortaya çıkarılan bir numaralı sorun.
  • Bellek dağıtımının performansı nasıl etkilediğini anlamak. TCMalloc (veya diğer mallocs) kullanmalı mıyım ve nasıl bilmeliyim? Çeşitli tahsis ve ayrılma parametrelerini nasıl ayarlamalıyım?
  • Nesne kopyalamadan gelen yükün ne zaman önemli olacağını (ve bu nedenle örneğin işaretçiye geçmesi gerektiğini) nasıl bilebilirim?
  • Ayrıca, bunları ne zaman kullanacakları konusunda bilgi sahibi olduğum sürece genellikle "optimizasyonlar" ile ilgileniyorum.

Gerçekten ilgilenmediğim şeyler:

  • "Yüksek Performanslı Hesaplama", bir terim daha fazla matematik / simülasyon odaklı uygulamalar gösteriyor gibi görünüyor.
  • C ++ ile çakıştığım için diğer dillere göre C ++ performansının tartışması.

Bir başlangıç ​​noktası olarak, bu kitabın bilen var mı? Verimli C ++, tasarıya uygun mu?


22
2017-09-10 17:17


Menşei


Montajcıyı anlıyor musunuz ve montaj listelerini üretebiliyor musunuz? Bu yeni başlayanlar için çok fazla olabilir, ancak C ++'nin kapakların altında ne yaptığı konusundaki anlayışımı arttırmak için bunu kullandım. - Jonathan Wood
C ++ Performans TR, ISO 18015'i önereceğim, ancak ANSI deposundan bile çok fazla maliyete (285 $) mal olacaktı. - Pete Becker
@PeteBecker - İşte ücretsiz bir taslak: open-std.org/JTC1/SC22/WG21/docs/TR18015.pdf. Bu yeterince iyi olabilir. - emsr
Sadece her zaman teorinin pratikte doğrudan sonuçlarının olmadığının farkında olun (kendi tecrübemden yazıyorum). Performansı artırmak istediğinizde daima kodunuzu izleyin. Gerçek dünya projesindeki kitaplardan her zaman iyi tavsiyeler değil, size iyileştirme ... :( - PiotrNycz
Önbellek efektleriyle başlamak için iyi bir yer bu ders kitabı örneğidir: Bir 2B dizisi üzerinde yineleme yaparken döngülerin sırası neden performansı etkiler? - Mysticial


Cevaplar:


Önerilerimi birkaç bölüme ayırmama izin verin.

C ++ Optimizasyonu

Bir başlangıç ​​noktası olarak, Agner Fog’ı tavsiye ederim. C ++ yazılımında optimizasyon. Bu kılavuz genel C ++ optimizasyon konularına mükemmel bir genel bakış sunar.

Genel Donanımı Anlamak

C ++ performansının iyi bir zihinsel modeline sahip olmak için, temeldeki donanımı da anlamanız gerekir. Bu ifadeyi düşünün:

a[7] = 5;

C ++ dil tarafında, kod satırı performans açısından sıkıcıdır: sadece bir bellek yazma. Ancak, gerçek donanım üzerinde, bu bellek yazma performansı büyüklük sıralarına göre değişebilir. Bu seviyede neler olduğunu anlamak için önbellekler, işlemci boru hattı, TLB, şube tahmini ve benzeri kavramları öğrenmeniz gerekir.

İşlemci önbelleklerine hızlı bir giriş olarak, makalemi öneririm İşlemci Önbellek Etkileri Galerisi. Önbellek ve bilgisayar belleği hakkında daha derin ve uzun (> 100 sayfa) tartışma Her Programcının Bellek Hakkında Bilmesi Gerekenler.

Modern bilgisayar donanımı hakkında genel bilgi sahibi olmak için, Bilgisayar Mimarisi: Kantitatif Yaklaşım, yaygın olarak önerilen kitaptır. Kitabı kendim okumadım, bunun yerine blogları ve deneyleri okuyarak öğrendim. Bununla birlikte, diğerleri kitabı çok faydalı buldular.

Belirli İşlemcileri Anlamak

Optimizasyon becerilerinizi geliştirmek için yaptığınız yolculuğun bir noktasında, farklı işlemcilerin özelliklerini tanımak için yararlı bulursunuz. Çok sayıda farklı Intel ve AMD işlemcisinin bir örneği, _mm_storeu_ps C ++ intrinsic gibi hizalanmamış SSE yönergelerini kullanmak için çok farklı cezalara sahiptir.

Farklı işlemcilerin özelliklerini öğrenmek için tavsiye ederim Intel, AMD ve VIA CPU'ların mikromimarisi: Montaj programcıları ve derleyici üreticileri için bir optimizasyon rehberi. Aslında, sadece devam edeceğim ve tüm optimizasyon kılavuzları Agner Fog'dan. Ayrıca, donanım satıcıları kendi donanımları için belgeler sunar.

Araçları Kullanmayı Öğrenmek

C ++ ve donanım performansının iyi bir zihinsel modeline sahip olmak, kodu optimize ederken çok kullanışlıdır. Ancak, doğru araçları kullanmayı öğrenmek en az yararlıdır. Muhtemelen optimizasyon için en iyi tavsiye "Öncelikle ölçmek" dir. Sadece basit bir kod bloğunun performansını, onu düşünerek anlamak çok zordur. Kodu çalıştırarak ve çeşitli şekillerde ölçerek çok fazla bilgi edineceksiniz.

Bunlar yaygın yararlı ölçümlerden bazılarıdır:

  • Zamanlama: sadece kodu çalıştırın ve zamanı ölçün
  • Örnekleme profil oluşturucuları
  • Enstrümantasyon profilleyicileri
  • İşlemci sayaçları

Özgün sorularınızın kapsamını tartıştığım için belirli araçlar için tavsiyelerde bulunmayacağım. Ayrıca, takım kendi başına büyük bir konudur: araçlar farklı donanım platformlarına, yazılım platformlarına ve maliyete göre farklılık gösterir (bazıları ücretsizdir, bazıları pahalıdır).

Ancak, C ++ kodunu optimize etmek için, uygun araçları bilmeniz ve kullanmanız gerektiğini bilmeniz gerekir.


25
2017-09-10 18:50



Aletleri öğrenmek ve nasıl ölçüleceğini söylemek çok daha önemlidir, çünkü bu şekilde optimizasyonlarınızın nasıl davrandığını ve nasıl gittiğini öğrenebilirsiniz. Donanım / os / derleyici şeyler ayaklarınızın altında hızla değişir, ancak kod / uygulamaların nasıl ölçüleceğini / profil oluşturulduğunu öğrenmek sürekli olarak yararlıdır. - Macke
Uygun araçları kullanmayı öğrenmek çok değerli bir yatırımdır. Pratikte kodu optimize etmek için araçları etkili bir şekilde kullanabilmek için derleyiciyi ve donanımı anlamanız gerekir. Örneğin, bir sahte önbellek satırı paylaşım sorununu düzeltmek istiyorsanız "önbellek çizgisinin" ne olduğunu bilmeniz gerekir. - Igor ostrovsky
Çoğunlukla, CPU'nun nereye gittiğini bildiğimi, onu yeterince optimize edebildiğimi (yani daha az iş yapabilmeyi, daha iyi veri yapıları seçmeyi vb.) Bulabildiğimi fark ettim .. ama evet, eğer eşyalarınızı olduğu gibi daha hızlı çalıştırmanız gerekiyorsa, o zaman donanım hakkında daha fazla bilgi sahibi olmanız gerekir. Sadece optimizasyon, çoğu şey gibi, beklediğimden çok daha yüksek bir seviyede başladığını buldum. (Özellikle yeni başlayanlar için. OP'nin yeterli olduğunu düşünüyorum, ama cevabınız da yeni başlayanlar tarafından okunacak.) - Macke


Valgrind senin ilk aracın olmalı.

Valgrind'in birçok aracı var, ancak cachegrind, algoritmanızın iyi bir veri lokalitesine sahip olup olmadığını görmenin harika bir yoludur. Bu hafıza darboğazlarını tespit edecektir. Callgrind, işleme darboğazlarını tanımlamanıza yardımcı olacak başka bir valgrind modülüdür.

Referanslar:

Cachegrind: http://valgrind.org/docs/manual/cg-manual.html

Callgrind: http://valgrind.org/docs/manual/cl-manual.html


11
2017-09-10 17:24





Önceki cevaplar en önemli düşünceyi verdi.

Sadece bir uyarı: bazı profiller (valgrind) yapın, hızlı kazanacağınız yer burası. Bundan sonra, önbellek optimizasyonları almaya çalışmak, SSE'ye bakmak… (en azından başlangıçta) küçük iyileştirme için çok daha fazla çaba gerektirecektir.

Ayrıca, C ++ büyük bir dil ve derleyiciler sihir yapar. Şablonlar, satır içi ve benzeri, derleyicinin C. gibi diğer dillerde mümkün olmayan büyük optimizasyonlar yapmasına izin verir. Bu nedenle, düşük seviyeli veri yapılarını kullanmayı düşünürken çok dikkatli olun. Bu, performans kaybına neden olabilir (ve bellek yönetiminde daha fazla hata ve daha fazla baş ağrısı).

STL ve BOOST kullanımı muhtemelen bazı hatalardan kaçınmanıza yardımcı olacaktır.


1
2017-09-10 19:26





Bu seviyede neler olduğunu anlamak için önbellekler, işlemci boru hattı, TLB, şube tahmini ve benzeri kavramları öğrenmeniz gerekir.

Bunları çok rahat bir şekilde tartışmak istiyorum.

  1. Önbellek - Temel olarak, çalışma grubunuzu önbellek içine sığdırmaya çalışırsanız, uygulamanızın muazzam hız kazanır.
  2. Dallar - Şubeler çok uzun zaman alırlar, çünkü bir hafızada bir blok okuması gerekir. Örneğin, x=1 daha hızlı olabilir if (needWrite) x=1; gereksiz yazılar yazsa bile.
  3. Şube tahmini - Bir öncekinden ötürü, CPU, bir dalın sonucunun kalıp eşleştirme algoritmalarını ne kullandığını 'tahmin etmeye çalışmaktadır. Bu üçlüyü tahmin etmek, hız kazancı sağlayabilir.
  4. İşlemci boru hatları, Yönerge Düzeyi Paralellik, süperskallar, kayıt yeniden adlandırma ve diğerleri - Bunlar çoğunlukla derleyici tarafından optimize edilmeli, bence.

1
2017-09-10 21:11