Evet, verilerinizin hem hizalanması hem de düzenlenmesi, yalnızca yüzde birkaç değil, yüzde birkaç ila yüzlerce arasında performansta büyük bir fark yaratabilir.
Bu döngüyü alın, yeterli döngü çalıştırıyorsanız iki talimat önemlidir.
.globl ASMDELAY
ASMDELAY:
subs r0,r0,#1
bne ASMDELAY
bx lr
Önbellekli ve önbelleğe sahip olmayan ve dal tahmininde önbellek ile ve önbelleksiz hizalama ile bu iki komutun performansını önemli miktarda değiştirebilirsiniz (zamanlayıcı keneleri):
min max difference
00016DDE 003E025D 003C947F
Kendinizi kolayca yapabileceğiniz bir performans testi. test edilen kodun etrafına düğüm ekleyin veya çıkarın ve doğru bir zamanlama işi yapın, test edilen talimatları önbellek çizgilerinin kenarlarına dokunacak kadar geniş bir adres aralığında hareket ettirin.
Veri erişimiyle aynı tür bir şey. Bazı mimariler, size bir veri hatası vererek, hizalanmamış erişimlerden (örneğin 0x1001 adresinde 32 bit okuma gerçekleştirme) şikayet eder. Bunlardan bazıları hatayı devre dışı bırakabilir ve performans isabetini alabilirsiniz. Atanmamış erişime izin veren diğerleri sadece performans isabetini alırsınız.
Bazen "talimatlar" ama çoğu zaman saat / otobüs çevrimleridir.
Çeşitli hedefler için gcc'deki memcpy uygulamalarına bakın. Diyelim ki 0x43 bayt olan bir yapıyı kopyalıyorsunuz, 0x42 bırakarak bir bayt kopyalayıp daha sonra büyük verimli parçalar halinde 0x40 baytı kopyalayan bir uygulama bulabilirsiniz, sonra son 0x2 iki ayrı bayt veya 16 bit aktarım olarak yapabilir. Kaynak ve hedef adresler 0x1003 ve 0x2003 ile aynı hizalamadaysa hizalama ve hedef devreye girer, sonra bir bayt, daha sonra büyük parçalar halinde 0x40, sonra 0x2, ancak biri 0x1002 ve diğer 0x1003 ise, o zaman alır çok çirkin ve çok yavaş.
Çoğu zaman otobüs döngüleri. Veya daha kötü transfer sayısı. ARM gibi 64 bit genişliğinde bir veri yoluna sahip bir işlemci alın ve 0x1004 adresine dört kelimeyle aktarma (okuma veya yazma, LDM veya STM), bu kelime ile hizalanmış bir adres ve mükemmel bir yasal, ancak veri yolu 64 ise bit genişliğinde tek komutun 0x1004'te 32 bit, 0x1008'de 64 bit ve 0x100A'da 32 bit olmak üzere üç aktarıma dönüşmesi muhtemeldir. Ancak aynı talimatı aldıysanız, ancak 0x1008 adresinde, 0x1008 adresinde tek bir dört sözcük aktarımı yapabilir. Her aktarımın ilişkili bir kurulum süresi vardır. Bu nedenle, 0x1004 - 0x1008 adres farkı tek başına birkaç kat daha hızlı olabilir, hatta bir önbellek kullanırken / esp ve hepsi de önbellek isabetidir.
Bundan bahsetmişken, 0x1000 vs 0x0FFC adresinde iki kelimelik bir okuma yapmış olsanız bile, önbellek özlemleri olan 0x0FFC, 0x1000'in bir önbellek satırı olduğu iki önbellek satırı okumasına neden olacak, rastgele bir önbellek satırı cezası zaten olacak erişim (kullanmaktan daha fazla veri okuma) ancak bu iki katına çıkar. Yapılarınızın nasıl hizalandığı veya genel olarak verileriniz ve bu verilere vb. Erişim sıklığınız önbellek bozulmasına neden olabilir.
Verileri işlerken tahliye oluşturabileceğiniz, gerçek şanssızlaşabileceğiniz ve önbelleğinizin yalnızca bir kısmını kullanarak sonuçlandırabileceğiniz gibi sonlandırabilir ve bir sonraki veri bloğu bir önceki blob ile çarpıştığında . Verilerinizi karıştırarak veya kaynak kodundaki işlevleri yeniden düzenleyerek, çarpışmalar oluşturabilir veya kaldırabilirsiniz, çünkü tüm önbellekler eşit şekilde oluşturulmaz, derleyici burada size yardımcı olmayacaktır. Performans vuruşunu veya iyileştirmeyi tespit etmek bile sizin üzerinizde.
Performansı artırmak için eklediğimiz her şey, daha geniş veri yolları, boru hatları, önbellekler, şube tahmini, çoklu yürütme birimleri / yolları vb. Çoğu zaman yardımcı olacaktır, ancak hepsinin kasıtlı veya yanlışlıkla kullanılabilecek zayıf noktaları vardır. Derleyici veya kütüphanelerin bu konuda yapabileceği çok az şey var, eğer performansla ilgileniyorsanız ayarlamanız gerekir ve en büyük ayar faktörlerinden biri kodun ve verilerin hizalanmasıdır, sadece 32, 64, 128, 256'ya hizalanmamıştır. bit sınırlarının yanı sıra, şeylerin birbirine göreli olduğu yerlerde, yoğun bir şekilde kullanılan döngülerin veya yeniden kullanılan verilerin aynı önbellek yolunda inmemesini istiyorsunuz, her biri kendi istediklerini istiyor. Derleyiciler, örneğin bir süper skaler mimari için talimatların sıralanmasına yardımcı olabilir, birbirlerine göre önemli olmayan talimatları yeniden düzenleyebilir,
En büyük gözetim, işlemcinin darboğaz olduğu varsayımıdır. On yıldan fazla bir süredir doğru olmamış, işlemciyi beslemek problemdir ve hizalama performansı isabetleri, önbellek atma, vb. Kaynak kodu düzeyinde bile küçük bir çalışma ile, bir yapıdaki verilerin yeniden düzenlenmesi, değişken / yapı bildirimlerinin sıralanması, kaynak kodu içindeki işlevlerin sıralanması ve verilerin hizalanması için biraz fazla kod kullanılması, performansı birkaç kez artırabilir veya Daha.