Bir işlemcide neden 32 kayıt var?


52

İş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?


2
Belli bir noktanın ötesinde, tüm yerel değişkenleriniz kayıtlara uyuyor. Çalıştığınız gerçek veriler yine de muhtemelen çok büyük
Niklas B.

14
Azalan dönüşler. Açıkçası, kayıtlar RAM'den "daha pahalıdır" (çeşitli anlamda) ya da sadece 8GB kayıt sayılabilir.
David Richerby

5
Bu kadar hızlı olmasının sebeplerinden biri de çoğunun olmaması.
stackErr

5
CPU'nun toplamda kaç tane kaydettirdiği ve bir kerede kaç tane kullanabileceğiniz arasında bir fark var.
Thorbjørn Ravn Andersen

CPU'lar ve GPU'lar gecikmeyi öncelikli olarak sırasıyla önbellek ve çoklu okuma ile gizler. Bu nedenle, CPU'ların az sayıda kaydı vardır, oysa GPU'larda onbinlerce kayıt vardır. Tüm bu dengelemeleri ve faktörleri tartışan GPU sicil dosyasındaki anket çalışmamı görün .
user984260,

Yanıtlar:


82

İ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 ( nO(n)


1
SPARC64 VIIIfx'in 256 FPR'sinden ve 32 ekstra pencere dışı GPR'inden bahsettim, sonraki bir veya iki komut için her biri 13 bit sağlayan bir Set XAR komutu ekleyerek başardım. HPC'yi hedef aldı, bu nedenle kayıt sayısı daha anlaşılır. Ayrıca daha fazla sicil ile ilişkilendirilen bazı takas ve teknikleri açıklayacaktım; ama daha yorucu (ve o zaman bile yorucu olmayan) bir cevabı önlemek için bilgeliği gösterdin.
Paul A. Clayton

2
Anlamlı ölçümler bulmak kolay olmasa da, "genel amaçlı" kod için daha fazla kayıtların azalan faydası üzerine biraz eklemek faydalı olabilir. Sanırım Mitch Alsup, 16'dan ziyade x86'yı 32 kayıtçıya genişletmenin, seçilen 8 ila 16 kayıt uzantısı için (ISTR)% 10-15'e kıyasla performansta yaklaşık% 3'lük bir artış elde edeceğini belirtti. Yük deposu ISA için bile, 64'e gitmek muhtemelen çok az yarar sağlar (en azından mevcut GP kodu için). (BTW, GPU'lar genellikle dişliler arasında kayıtları paylaşır: örn., Bir konu, diğer
Paul A. Clayton,

Genellikle üst düzey dillerle ilişkili olan çevre yönetiminin (dolayısıyla alfa-dönüşüm) aslında kayıt düzeyinde kullanıldığını görmek ilginçtir.
babou

@ PaulA.Clayton Her zaman IA-64'ün en fazla ISA kaydına sahip mimari olduğunu düşündüm
phuclv

@ LưuVĩnhPhúc SPARC64 VIIIfx, HPC'ye özgüdür. Bilginize, Am29k (yaklaşık tanıtıldı 1987-8 ) (8 şube kayıtları ve bunların işlevi diğer bazı uluslararası denetim standartları GPRS olacağını bir döngü sayaç kaydını var) Itanium daha GPR'ler olan küresel 64 ve 128 pencereli GPRS vardı.
Paul A. Clayton,

16

Kayıt sayısını sınırlamak için sadece iki neden:

  • Beklenecek çok az kazanç: Mevcut Intel / AMD x64 modelleri gibi CPU 32kByte ve daha fazla L1-D önbelleğine sahiptir ve L1 önbelleğine erişim genellikle yalnızca bir saat döngüsü alır (tam bir RAM için yaklaşık yüz saat çevrimi ile karşılaştırıldığında) erişim). Bu nedenle, L1 önbelleğindeki verilere kıyasla, kayıtlarda daha fazla veriye sahip olmanın az kazancı var.
  • Ek hesaplama maliyetleri: Daha fazla kayıt sahibi olmak, bilgisayarı gerçekten daha yavaş hale getirebilecek bir ek yük yaratır:
    • Çok görevli ortamlarda, bir görev anahtarı genellikle işlemin belleğe bırakılan tüm işlem kayıtlarının içeriğini kaydetmeli ve girilecek işlemin içeriğini yüklemelidir. Ne kadar çok kaydınız varsa, bu o kadar uzun sürer.
    • Benzer şekilde, kayıt pencereleri olmayan mimarilerde, basamaklı işlev çağrıları aynı kayıt kümesini kullanır. Bu yüzden, bir A fonksiyonunu çağırmak için bir B fonksiyonu, B ile aynı kayıt kümesini kullanır. Bu nedenle, B kullandığı tüm kayıtların içeriğini kaydetmelidir (hala A'nın değerlerini tutar) ve geri dönmeden önce geri yazmak zorundadır (bazı arama kurallarında, B'yi çağırmadan önce kayıt içeriğini kaydetmek A'nın işidir, ancak havai benzer). Ne kadar çok kaydettirirseniz, bu tasarruf o kadar uzun sürüyor ve bu nedenle bir işlev çağrısı daha pahalı hale geliyor.

L1 önbellek için nasıl çalışır, böylece kayıt defterleriyle aynı sorunu yaşamadık?
babou

4
Yüksek performanslı işlemcilerde L1 Dcache gecikmesi daha tipik olarak 3 veya 4 döngüdür (adres üretme dahil), örneğin, Intel'in Haswell 4 döngü gecikme süresine sahiptir (veri bağımlılığı kayıt gecikme süresine sahip olmaması da boru hattında gizlenmesi daha kolaydır). Dcache ayrıca çevrim başına (örneğin, 2 okuma, Haswell için 1 yazma) bir kayıt dosyasından (örneğin, 4 okuma, 6 dosyayı kopyalayan Alpha 21264 için 6 yazma, 4 okuma ile 2 dosya daha hızlı) daha az erişimi desteklemeye meyillidir. 8).
Paul A. Clayton

@ PaulA.Clayton: L1 önbelleği 3-4 döngü gecikme süresine sahipse, bu, örneğin 64 kelimelik adres alanına sahip birkaç 64 kelimelik tek döngülü bellek kümesine sahip olmanın bazı yararları olabileceğini gösterir. "sıfır / doğrudan kaydet" komutlarını atayın, özellikle sıfır olmayan tüm değerleri itmenin bir yolu, ardından hangi kelimelerin sıfır olmadığını söyleyen bir sözcük ve sonra bunları geri getirmenin bir yolu varsa (atılmayan tüm kayıtları sıfırlama) . Birçok yöntemde 16 ile 60 kelime arasında yerel değişken vardır, bu nedenle 3-4 devirden bire bir olanlara erişim süresinin kesilmesi yardımcı olabilir.
supercat

@supercat Çeşitli yığın (ve global / TLS [örn., Knapsack]) önbellek fikirleri akademik belgelerde ve imza tamponu ( PDF ) gibi kullanımda olduğu gibi mekanizmalarda sunuldu . Bu konuşkanlaşıyor (bu yüzden muhtemelen bitmeli ya da başka bir yere gitmeli).
Paul A. Clayton

4

Ç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!


2

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.


2

Ö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.


1

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.O(n2)

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 .


“Her sicilden girdi alabilmeli ve her sicilde çıkabilmelidirler.” - Bunun tipik olarak bir otobüsle yapılmasını beklerdim, her kayıt için ALU'lara ayrı bir bağlantı olması gerekmez.
kullanıcı253751

1
@ immibis: Verileri 300 pikosaniye cinsinden taşımak istiyorsanız, bir veri yolu bunu yapmaz. Ve bir çok veriyi dolaştırmak istiyorsanız (örneğin, iki işleve sahip üç komut ve her biri aynı döngüde bir sonuç), bir otobüs kesinlikle işe yaramayacaktır.
gnasher729

0

MIPS ISA, Hennessy ve Patterson, Bilgisayar Organizasyonu ve Tasarımı 4. basım p. 176, bu özel soruyu doğrudan cevaplar:

Daha küçük hızlıdır. Hız arzusu, MIPS'nin çok fazla olmaktan ziyade 32 kaydının olmasının nedenidir.

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.