İşlemcilerin neden 32 kayıtta durduğunu hep merak etmişimdir. Makinenin en hızlı parçası, neden sadece daha fazla kayıt yapan daha büyük işlemciler üretmiyor? Bu daha az RAM'e gitmek anlamına gelmez mi?
İşlemcilerin neden 32 kayıtta durduğunu hep merak etmişimdir. Makinenin en hızlı parçası, neden sadece daha fazla kayıt yapan daha büyük işlemciler üretmiyor? Bu daha az RAM'e gitmek anlamına gelmez mi?
Yanıtlar:
İlk olarak, tüm işlemci mimarileri 32 kayıtta durmuyor. Talimat setinde 32 yazmaç bulunan hemen hemen tüm RISC mimarileri 32 tamsayılı yazmaç ve 32 daha fazla kayan nokta yazmaçına sahiptir (yani 64). (Kayan nokta "add", "add" tamsayısından farklı kayıtlar kullanır.) SPARC mimarisinin kayıt pencereleri vardır. SPARC'da bir seferde yalnızca 32 tam sayı kaydına erişebilirsiniz, ancak kayıtlar bir yığın gibi hareket eder ve bir kerede yeni kayıtlar 16'yı itip açabilirsiniz. HP / Intel’den gelen Itanium mimarisinde, talimat setinde açığa çıkan 128 tam sayı ve 128 kayan nokta yazıcısı bulunuyor. NVidia, AMD, Intel, ARM ve Imagination Technologies'in modern GPU'ları, hepsi kayıt dosyalarında çok sayıda kayıt kullanıyor. (Bunun NVidia ve Intel mimarileri için geçerli olduğunu biliyorum, AMD, ARM ve Imagination komut kümelerini pek bilmiyorum ama kayıt dosyalarının da büyük olduğunu düşünüyorum.)
İkincisi, çoğu modern mikroişlemci , kaynakların yeniden kullanılması gereğinden kaynaklanan gereksiz serileştirmeyi ortadan kaldırmak için kayıt adlandırma işlemi uygular ; bu nedenle, temel fiziksel kayıt dosyaları daha büyük olabilir (bazı makinelerde 96, 128 veya 192 kayıt sayısı). Derleyicinin, zamanlayıcıya daha büyük bir kayıt dosyası sunarken, çok sayıda benzersiz kayıt adı oluşturması gerekir.
Talimat setinde belirtilen kayıt sayısını daha da arttırmanın zor olmasının iki nedeni vardır. Öncelikle, her komuttaki kayıt tanımlayıcılarını belirtebilmeniz gerekir. 32 yazmaç 5 bitlik bir kayıt belirticisi gerektirir, bu nedenle 3 adresli talimatlar (RISC mimarilerinde ortak olarak kullanılır) 32 kayıt bitinden sadece 15 tanesini kayıtları belirtmek için harcar. Bunu 6 veya 7 bite yükseltirseniz, kodları ve sabitleri belirlemek için daha az yeriniz olur. GPU'lar ve Itanium'un daha büyük talimatları var. Daha büyük talimatların bir maliyeti vardır: daha fazla talimat hafızası kullanmanız gerekir, bu nedenle talimat önbelleği davranışınız daha az idealdir.
İkinci sebep ise erişim zamanı. Bir belleği ne kadar büyük yaparsanız, bu veriye o kadar yavaş erişir. (Sadece temel fizik açısından: veriler 2 boyutlu alanda saklanır, bu nedenle bit saklıyorsanız , belirli bir bit ile ortalama uzaklık .) Bir kayıt dosyası sadece bir küçük, çoklu bağlantı noktalı bellek ve daha büyük hale getirme konusundaki kısıtlamalardan biri, daha büyük kayıt dosyasını yerleştirmek için makinenizi yavaşlatmaya başlamanız gerektiğidir. Genellikle toplam performans açısından bu bir kayıptır. O ( √
Kayıt sayısını sınırlamak için sadece iki neden:
Çok sayıda kodun çok sayıda bellek erişimi vardır (% 30 tipik bir rakamdır). Bunun dışında, tipik olarak yaklaşık 2 / 3'ü okuma erişimi ve 1 / 3'ü yazma erişimidir. Bu, dizilere erişmek, nesne üye değişkenlerine erişmek vb. Kadar kayıtların tükenmesinden kaynaklanmamaktadır.
Bu, C / C ++ 'ın nasıl yapıldığına bağlı olarak bellekte (veya veri önbelleğinde) yapılmalıdır. Eğer derleyici çılgınca dolaylı işaretçi hileleri kullanarak willy-nilly değişkenlerine yazmayacağınızı tahmin ederse, bunları sicillere koyacaktır ve bu, fonksiyon değişkenleri için harika bir sonuçtur, ancak küresel olarak erişilebilir olanlar için (genellikle, mallocdan çıkan her şey) ()) çünkü küresel devletin nasıl değişeceğini tahmin etmek aslında imkansız.
Bu nedenle, derleyicinin yine de 16 genel kullanım kaydından daha fazlasını içeren bir şey yapması yaygın değildir. Bu nedenle tüm popüler mimarların bu kadarı var (ARM 16'sı var).
MIPS ve diğer RISC’ler 32’ye sahip olma eğilimindedir, çünkü bu kadar sayıda yazmaçya sahip olmak çok zor değildir - maliyet yeterince düşüktür, bu yüzden biraz “neden olmasın?”. 32'den fazlası çoğunlukla işe yaramaz ve kayıt dosyasının erişilmesini daha uzun hale getirme dezavantajına sahiptir (kayıt sayısının her iki katına çıkması potansiyel olarak biraz daha fazla gecikme ekleyen çoklayıcı katmanı ekler ...). Aynı zamanda ortalama olarak talimatları biraz daha uzatır - bu, talimat hafıza bant genişliğine bağlı programları çalıştırırken, fazladan yazmaçlarınızın sizi gerçekten yavaşlattığı anlamına gelir!
İşlemciniz düzenliyse ve yeniden adlandırma kaydı yapmıyorsa ve döngü başına çok sayıda işlem yapmaya çalışıyorsanız (3'ten fazla), o zaman teoride döngü başına op sayınız arttıkça daha fazla kayıt yapmanız gerekir. Bu nedenle, Itanium'un bu kadar çok kaydı var! Ancak pratikte, sayısal kayan nokta veya SIMD yönelimli kod dışında (ki Itanium gerçekten iyi), çoğu kod bu döngü başına 3 ops'tan daha fazlasını düşürebilen, çok fazla bellek okuma / yazma ve atlama yapacaktır. (özellikle veritabanları, derleyiciler, javascript, emülasyon vb. Itanium'u baturan da buydu.
Her şey hesaplama ve yürütme arasındaki farka iniyor!
Kim sana işlemci her zaman 32 kayıt olduğunu söyler ? x86 8, ARM 32-bit ve x86_64 16, IA-64 128 ve daha pek çok sayıya sahip. Bir göz atabilirsiniz burada . MIPS, PPC veya komut setinde 32 genel amaçlı kayıt olan herhangi bir mimaride bile, sayı 32'den fazladır, çünkü her zaman hala bayrak kayıtları (varsa), kontrol kayıtları ... yeniden adlandırılmış kayıtları ve donanım kayıtları içermez.
Her şeyin bir bedeli vardır. Kayıt sayısı büyüdükçe, görev değiştirme yaparken ne kadar işiniz olursa, komut kodlamasında o kadar fazla alana ihtiyacınız olur. Daha az kaydınız varsa, bazı bilgi işlem gerektiren kodlarda, kayıtların eksik olması durumunda işlevlerini çağırırken ve geri dönerken ya da işleri değiştirirken çok fazla saklama ve geri yükleme yapmanız gerekmez.
Ayrıca, kayıt dosyası büyüdükçe, daha pahalı ve karmaşık olacaktır. SRAM en hızlı ve en pahalı RAM'dir, bu nedenle yalnızca CPU önbelleğinde kullanılır. Ancak yine de daha ucuz ve aynı kapasiteye sahip bir kayıt dosyasından daha az alan kaplıyor.
Örneğin, tipik bir Intel işlemcisi "resmen" 16 tam sayı ve 16 vektör kaydına sahiptir. Fakat gerçekte, çok daha fazlası var: İşlemci "yeniden adlandırma kaydını" kullanıyor. Eğer reg3 = reg1 + reg2 komutunuz varsa, reg3'ü kullanan başka bir komut henüz tamamlanmamışsa sorun yaşarsınız - önceki talimat tarafından okunmadan önce reg3'ün üzerine yazması durumunda yeni talimatı uygulayamazsınız.
Bu nedenle, yaklaşık 160 kadar gerçek kayıt var. Bu yüzden yukarıdaki basit talimat "regX = reg1 + reg2" olarak değiştirildi ve regX'in reg3 içerdiğini hatırlayın. Yeniden adlandırılmış kayıtlar olmadan, sıra dışı çalıştırma suda kesinlikle ölmüş olur.
Ben elektrik mühendisi değilim, ancak sicil sayısını sınırlama sebebinin bir diğer olasılığını yönlendirme olduğunu düşünüyorum. Sınırlı sayıda aritmetik ünite vardır ve her kayıttan girdi alabilmeli ve her kayda çıktı alabilmelidir. Bu, özellikle her döngü için birçok talimat uygulayabilen pipeline programlarınız olduğunda geçerlidir.
Bunun basit bir versiyonu karmaşıklığa sahip olacaktı, kayıt sayısını arttırılamaz hale getirdi ya da başka bir yolla her şeyi daha iyi bir karmaşıklığa sahip olacak şekilde yönlendirmenin yeniden tasarlanmasını gerektirdi.
Ivan Godard'ın Değirmen İşlemcisi ile ilgili görüşmelerinden bazılarını izleyerek bu cevabı aldım. Mill CPU'nun yenilikçiliğinin bir kısmı, rasgele kayıtlara çıktı verememenizdir - çıktıların tümü bir kayıt yığınının veya "kayışın" üzerine itilir, bu nedenle her zaman çıktının nereye gideceğini bildiğiniz için yönlendirme sorunlarını azaltır. Girdi kayıtlarını aritmetik birimlere almak için yönlendirme problemleri olduğunu unutmayın.
Sorun bildirimi için The Mill CPU Architecture - The Belt (9/2) ve Mill'in çözümü konusuna bakın .