CPU önbelleği için optimize ederken ne önemlidir? (C cinsinden)?


13

Bu iki soruyu okurken , bellekte büyük miktarda veriyle uğraşırken CPU önbellekleme davranışını anlamanın önemli olabileceğini görüyorum. Optimizasyon araç kutusuna başka bir araç eklemek için önbelleğin nasıl çalıştığını anlamak istiyorum.

CPU önbelleğinin çalışma biçimiyle ilgili temel noktalar nelerdir, böylece onu mantıklı kullanan kod yazabilir miyim? İlgili olarak, önbellek kullanımının yavaşlayıp yavaşlamadığını görmek için profil kodu oluşturmanın bir yolu var mı?


Önbellekler her yerde aynı değildir; en açıkçası, boyut olarak değişir. Derin sırları öğrenmeyi beklemeyin, sadece iyi uygulamalar (Michael Borgwardt'ın tavsiyesi gibi).
David Thornley

Yanıtlar:


17

+1 “Birlikte erişilecek şeyleri yan yana tut”; unutması kolay olan budur.
Donal Fellows

Derleyiciye optimizasyon yapmasını söyleyin.
sağ ara

@WTP: sağ eklendi.
Michael Borgwardt

Ayrıca, muteksleri iyi ayrılmış halde tutun. Muteksi değiştirmek, içerdiği tüm önbellek hatlarını tüm CPU'larda yıkayın. Tek bir önbellek satırında 2-3 muteks elde etmeyi başardıysanız, bu büyük bir performans isabeti olabilir.
Vatin

12

Bu sorunun karmaşıklığı, günümüzde insan kavrayışının ötesinde olmuştur. (Son 5 yıldan bu yana böyle olmuştur.) Kısa vektör paralelliğiyle (SIMD) birleştirin ve kodu elle optimize etmenin artık ekonomik olarak mümkün olmadığı konusunda umutsuz bir hissiniz var - bu mümkün değil, ama artık maliyet etkin olmayacak.

Mevcut yaklaşım, bilgisayarlara nasıl optimize edileceğini öğretmek - farklı yapılarla (döngüler, veri yapısı, algoritmalar) aynı yanıtları hesaplayan kod varyasyonları yaparak ve performansı otomatik olarak değerlendirmektir. Kod dönüşüm kuralları çok titiz bir matematiksel modelle belirtilmiştir, böylece hem bilgisayar bilimcilerinin anlayabileceği hem de bilgisayarların çalıştırabileceği bir şeydir.

Aşağıda Larry OBrien tarafından yanıtlarından birinde yayınlanan bir bağlantı yer almaktadır .

http://onward-conference.org/2011/images/Pueschel_2011_AutomaticPerformanceProgramming_Onward11.pdf


2
en hızlı BLAS uygulaması (GotoBLAS) matris çarpımı için maksimum önbellek kullanımını sağlamak için elle optimize edilmiş kodu kullanır
quant_dev

2

Önbellekleri anlamak ve optimize etmek oldukça mümkündür. Donanımı anlamakla başlar ve sistemi kontrol altında tutmakla devam eder. Sistem üzerinde ne kadar az kontrole sahip olursanız başarılı olma olasılığınız o kadar düşük olur. Boşta olmayan bir grup uygulama / iş parçacığı çalıştıran Linux veya Windows.

Çoğu önbellek özelliklerinde biraz benzerdir, isabet aramak için adres alanının bir bölümünü kullanın, bir derinliğe (yollara) ve bir genişliğe (önbellek çizgisine) sahiptir. Bazılarının yazma arabellekleri vardır, bazıları yazmalarda önbellek üzerinden yazmak veya atlamak için yapılandırılabilir.

Bu önbelleğe çarpan tüm bellek işlemlerinin farkında olmanız gerekir (bazı sistemlerde görevi kolaylaştırmak için bağımsız talimatlar ve veri önbellekleri vardır).

Belleğinizi dikkatli bir şekilde yönetmeyerek kolayca bir önbelleği kullanabilirsiniz. Örneğin, işlediğiniz birden çok veri bloğunuz varsa, bunları önbellekte tutmayı umuyorsanız, ancak bunlar isabet / özledim denetimine göre birden fazla olan adreslerde, örneğin 0x10000 0x20000 0x30000 diyelim ve daha fazlasına sahipseniz bunlar önbellekteki yollardan çok daha hızlı bir şekilde, önbellek açıkken oldukça yavaş çalışan, önbellek kapalıyken olduğundan daha yavaş çalışan bir şey yapabilirsiniz. Ancak bunu belki 0x10000, 0x21000, 0x32000 olarak değiştirin ve bu, tahliyeleri azaltarak önbellekten tam olarak yararlanmak için yeterli olabilir.

Alt satır, bir önbellek için optimize etmenin anahtarı (sistemi oldukça iyi tanımak dışında) performans için ihtiyaç duyduğunuz tüm şeyleri aynı anda önbellekte tutmak ve bu verileri sahip olabileceğiniz şekilde organize etmektir. hepsini önbellekte bir kerede. Kod yürütme, kesmeler ve diğer düzenli veya rasgele olaylar, kullandığınız bu verilerin önemli bölümlerini ortaya çıkarmayı engeller.

Aynı şey kod için de geçerlidir. Önbellekte tutmak istediğiniz diğer kodlarla çarpışmaları önlemek için kodun yaşadığı yerleri kontrol etmeniz gerektiğinden biraz daha zordur. Burada ve orada tek bir kod satırı ekleyen bir önbellekten veya hatta tek bir nop ekleyen herhangi bir kodu test ederken / profil oluştururken, kodun aynı kod için bir derlemeden diğerine geçtiği adresleri değiştiren veya değiştiren her şey, önbellek satırları bu kodun içine girer ve tahliye edilenleri ve kritik bölümler için olmayanları değiştirir.


1

Hem nwong's hem de Michael Borgwardt'ın cevapları iyi tavsiyeler veriyor.

Ayrıca, önce derleyicinin bu konulardaki optimizasyonlarına güvenin.

Yeni bir GCC derleyicisi kullanıyorsanız, __builtin_prefetchişlevini (parsimony ile) kullanabilirsiniz . Stackoverflow ile ilgili bu cevaba bakınız .

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.