Motorların neden aynı mimarideki yeni işlemciler için optimize edilmesi gerekiyor?


39

Yeni bir işlemci üretimi piyasaya sürüldüğünde, çoğu web sitesi oyun motorları ve programlarının yeni donanım için optimize edilmesi gerektiğini bildirmektedir. Nedenini tam olarak anlamadım. Bir işlemci genellikle ne tür komutlar kullandığını tanımlayan bir mimariye sahiptir. Bugünlerde hepimizin kullandığı kişi amd_x86_64. Tüm işlemciler aynı mimariyi kullanıyorsa, neden herhangi bir program veya derleyicinin güncellenmesi gerekir? Elbette, makine kodunun yürütülmesini optimize eden yeni işlemcinin boru hattında İÇERİKLİ özellikler var, ancak mimarlık yapmazsa neden makine kodunun değiştirilmesi gerekiyor?


Yorumlar genişletilmiş tartışmalar için değildir; bu konuşma sohbete taşındı .
Josh

14
"İhtiyaç", örneğin Windows’un yeni bir CPU nesnesini desteklemesi gerektiği gibi (ya da Windows 7’de olduğu gibi değil, ilke olarak mükemmel bir şekilde çalışacak) gereğinden% 3-4 daha fazla güç kullanmak hariç, örneğin Ryzen ile para cezası. Bu ayar sadece CPU'dan biraz daha fazla sıkmaya çalışmak ve azami seviyeye yaklaşmakla ilgilidir. Gerçekçi olarak, farklı çizelgeleme ve birkaç yeni talimat kullanılması nedeniyle bağlamsız örneklerde toplam% 1-2 oranında kazanabilirsiniz.
Damon

2
Sırf iki işlemcinin aynı işlemleri gerçekleştirebilmesi, bu işlemlerin her iki işlemcide de aynı performansa sahip olması anlamına gelmiyor ...
Mehrdad

Yığın Taşması ile ilgili bir soruya bakın: mtune gerçekte nasıl çalışır?
Marc.2377,

Yanıtlar:


54

Çünkü aynı mimarinin farklı nesilleri farklı komut kümelerine sahip olabilir .

Örneğin, Streaming SIMD Extensions muhtemelen en iyi bilinen x86 komut setidir, ancak henüz bir x86 mimarisi olmasına rağmen, SSE, SSE2, SSE3 ve SSE4 var.

Bu nesillerin her biri, belirli işlemleri gerçekleştirmenin daha hızlı yollarını sağlayan yeni talimatlar içerebilir. Oyunlarla ilgili olabilecek bir örnek nokta ürün talimatları olabilir.

Dolayısıyla, bir oyun motoru önceki nesil bir mimarlık için derlenmişse, bu yeni talimatları desteklemeyecektir. Benzer şekilde motoru daha yeni talimatlar için optimize etmek gerekebilir; Örneğin SSE4 , yapı dizisi verileri üzerinde çalışan nokta ürün talimatlarını desteklemektedir. Bu yeni talimatlardan yararlanabilecek bir optimizasyon, veri düzeninizi yapı dizisi olarak değiştirmek olacaktır.


1
@ Panzercrisis - düzenleme öneriniz için teşekkür ederiz. Açık olmak gerekirse, asıl soru kendi kodunuzla ilgili değildi, motor koduyla ilgiliydi, bu nedenle "kendi kodunuzu optimize edin" iyi bir düzenleme önerisi değil. Ancak, "optimize etmek" derken "motor kodunu optimize etmek" derken netleştirmek zorunda olduğumu vurgulamak istedim, bu yüzden bunu almak için düzenleme yaptım.
Maximus Minimus 19:17

37

Maximus'un cevabı doğrudur, sadece hikayenin bir parçasını daha vermek istiyorum:

Donanımın kendisi, yeni girilen talimatlardan bağımsız olarak kodlama şeklinizi değiştirmeniz gereken şekilde değişir.

  • Artan veya azalan önbellek miktarları, önbellek optimizasyonu / önbellek geçersiz kılma sorunları hakkında endişelenmeniz gerektiği anlamına gelir. Daha fazla önbellek, küçük verilerle, verinin performans endişeleriyle karşı karşıya kalırken sürekli olduğundan emin olmaya daha az odaklanabileceğiniz anlamına gelir. Daha az önbellek, bunun bir sorun olabileceği anlamına gelir ve çok az önbellek, bazı büyük veri yapılarında, hiçbir şekilde önemi olmayacağı anlamına gelir.

  • Yeni önbellek seviyeleri, daha büyük veri kümelerini nasıl düzenlediğiniz hakkında daha fazla düşünmeniz gerektiği anlamına gelir (L1, vs L2, vs L3 ve L4).

  • Daha fazla çekirdek, çoklu iş parçacığı uygulamalarına nasıl daha iyi gideceğiniz ve uygulamanızın çok işlemli bir ortamda nasıl ölçekleneceği hakkında düşünmeniz gerektiği anlamına gelir.

  • Daha hızlı saatler, sistem gecikmesi olarak CPU hesaplama hızını düşünmek zorunda olduğunuzdan daha fazla bellek gecikmesi düşünmeye başlamanız gerektiği anlamına gelir.

  • Bir sistemdeki FPU sayısı artık çekirdek başına tam sayı ALU sayısıyla eşleşmeyebilir (AMD'nin böyle mimarileri vardır / vardır).

  • Benim saydığım bir işlemi hesaplamak için gereken saat döngüsü sayısı azaldı veya arttı.

  • Mevcut kayıt sayısı değişti.

Bunların hepsinin, önceki ISA'da aynı mimari ile ilgili mimarinin altında yatan ya da olumsuz olan varsayımlar yapan programlar üzerinde gerçek bir etkisi var.


"Artan veya azalan önbellek düzeyleri, önbellek tutarlılığı konusunda daha az endişelenmeniz gerektiği anlamına gelir." - neredeyse her CPU önbellek uyumludur. Yanlış paylaşım mı demek istiyorsun? Neredeyse herhangi bir CPU $ satırı bile neredeyse her zaman 64 B ...
Maciej Piechotka

1
Maciej sadece önbellek tutarlılığı konusundaki ifadenizi alıyordu :) Muhtemelen "önbellek optimizasyonu" veya başka bir şey demek istediniz. Önbellek tutarlılığı, bir sistemin N bağımsız önbellekleri olsa bile, yazılımın belleğini tutarlı bir şekilde şeffaf bir şekilde tutabilmesidir . Bu tamamen boyutuna dik. TBH ifadesi gerçekten alakalı değil ancak cevabınız (özellikle 5 ve 6. puanlar) soruyu kabul edilen IMO'dan daha iyi ele alıyor :) Belki mimari ve u-mimarisi arasındaki farkı vurgulamak daha da öne çıkacaktır.
Margaret Bloom

4
“Çarpma işleminden daha fazla zaman alan çarpma gibi, bugün modern intel ve CPUS'ta olduğu gibi aynı zaman alıyor” Bu doğru değil. Boru hatlı mimarilerde gecikme (sonuç hazır olduğunda) ile verim (döngü başına kaç tane yapabileceğinizi) arasında ayrım yapmanız gerekir. Modern Intel işlemcilere yönelik int'nin eki 4 ve 1 gecikme süresi içeriyor. Multiply 1 ve gecikme süresi 3 (veya 4). Bunlar her mimaride değişen ve optimizasyona ihtiyaç duyan şeylerdir. Örn pdepRyzen 1 istihbarattaki döngüsünü ama 6 alır böylece Ryzen üzerinde kullanmak istemeyebilirsiniz.
Christoph

2
@Clearer Burada CPU'lardan bahsettiğimizi biliyorum, ancak GPU'lar için hiç programlanmadınız mı? Aynı kod, CUDA'daki donanım özelliklerini dikkate almak zorunda olduğunuz sık sık farklı performans sonuçları verir . Oradan geldiğim yer, önbellek büyüklüğünün (paylaşılan bellek, yönetilen L1 önbellek) CUDA'da bir şeyi nasıl kodladığınızı göz önünde bulundurmam gerekiyor.
opa

2
@Christoph doğru. Bağladığınız kıyaslama bir dizi üzerinde döngü c[i] = a[i] OP b[i](yani işlem başına 2 yük ve 1 mağaza) için çok düşük hesaplama yoğunluğu nedeniyle zamanlara bellek bant genişliği hakimdir. Dizi boyutu L1D'ye uygunsa IDK gösterilmez. ( gcc4.9 -Ofastbüyük olasılıkla bu döngüler otomatik olarak vektörleştirilmiştir, bu nedenle karmaşık tamsayı kodunun bir parçası olarak normal skaler işlemlerin maliyetini bile ölçemezsiniz). Bu sayfanın ilk satırı ÖNEMLİ: Yararlı geri bildirim, bu önlemlerin bazılarının ciddi şekilde hatalı olduğunu ortaya koydu. Büyük bir güncelleme yolda .
Peter Cordes

2

Yeni talimatlar için destek gibi büyük değişikliklerin ötesinde bile, mikroişlemci üreticileri performanslarını iyileştirmek için tasarımlarını sürekli değiştiriyor ve her yeni tasarım, her talimat veya teknik için farklı göreceli performansa sahip olabilir . Belki Model X için dikkatlice optimize edilmiş branşsız bir kod yazmışsınızdır, ancak Model Y, kodun branşsız versiyonu için yanlış öngörü cezalarını azaltan gelişmiş bir branş tahminde bulunmuştu. . Belki de Y Modeli, belirli bir yüksek gecikmeli komutun daha fazla paralelliğini desteklemektedir, böylece şimdi bu talimatın kontrolsüz bir döngüsü daha iyi bir performans elde ederken, X Modeli'nde daha kısa bir sekans daha iyi olmuştur.

Herhangi bir problem birçok yolla çözülebilir ve her program optimizasyon açısından birbirine kenetlenen bir takas ve kaynak tahsisatıdır. Bu kaynakların mevcudiyetinde veya bu kodlar bakımından belirli bir kod parçasının maliyetindeki küçük değişiklikler bile, bir kod parçasına veya başka birine önemli bir performans avantajı sağlayan kademeli bir etkiye sahip olabilir. Yükseltilmiş bir yonga " her şeyden daha fazlasına " sahip olsa bile, her şeyin ne kadar daha fazlası dengeyi değiştirebilir.

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.