@ jalf'ın cevabı nedenlerin çoğunu kapsıyor, ancak bahsetmediği ilginç bir ayrıntı var: Dahili RISC benzeri çekirdek, ARM / PPC / MIPS gibi bir komut setini çalıştırmak için tasarlanmamıştır. X86 vergisi yalnızca güce aç kod çözücülerde değil, bir dereceye kadar çekirdek genelinde ödenir. yani bu sadece x86 komut kodlaması değildir; tuhaf anlamlara sahip her talimat.
Intel'in, talimat akışının x86 dışında bir şey olduğu ve komutlarla doğrudan uops'la eşleştiği bir işletim modu oluşturduğunu varsayalım. Ayrıca, her bir CPU modelinin bu mod için kendi ISA'sına sahip olduğunu varsayalım, bu nedenle iç kısımları istedikleri zaman değiştirmekte özgürler ve bu alternatif formatın komut-kod çözme işlemi için minimum miktarda transistör ile bunları açığa çıkarıyorlar.
Muhtemelen yalnızca x86 mimari durumuna eşlenmiş aynı sayıda kayda sahip olursunuz, böylece x86 işletim sistemleri, CPU'ya özgü komut setini kullanmadan bağlam anahtarlarına kaydedebilir / geri yükleyebilir. Ancak bu pratik sınırlamayı atarsak, evet, birkaç tane daha yazmaçımız olabilir çünkü normalde mikrokod 1 için ayrılmış gizli geçici yazmaçları kullanabiliriz .
Daha sonraki ardışık düzen aşamalarında (yürütme birimleri) değişiklik yapmayan alternatif kod çözücülerimiz varsa, bu ISA'nın hala birçok x86 eksantrikliği olacaktır. Çok güzel bir RISC mimarisi olmazdı. Tek bir talimat çok karmaşık olmazdı, ancak x86'nın diğer çılgınlıklarının bir kısmı hala orada olacaktı.
Örneğin: sola / sağa kaymalar, vardiya sayısı bir olmadığı sürece Taşma bayrağını tanımsız bırakır, bu durumda OF = olağan işaretli taşma tespiti. Döndürmeler için benzer çılgınlık. Ancak, açığa çıkarılan RISC talimatları bayraksız vardiyalar vb. Sağlayabilir (genellikle bazı karmaşık x86 komutlarına giren birden çok uop'tan yalnızca bir veya ikisinin kullanımına izin verir). Yani bu aslında ana karşı argüman olarak geçerli değil.
Bir RISC ISA için tamamen yeni bir kod çözücü yapacaksanız, RISC talimatları olarak açığa çıkarılacak x86 komutlarının parçalarını seçip seçmesini sağlayabilirsiniz. Bu, çekirdeğin x86 uzmanlığını bir şekilde azaltır.
Tekli uop'lar çok fazla veri tutabileceğinden, komut kodlaması büyük olasılıkla sabit boyutlu olmayacaktır. Tüm insn'lerin aynı boyutta olması durumunda anlamlı olandan çok daha fazla veri. Tek bir mikro-kaynaştırılmış uop, 2 yazmaçlı ve 32bit yer değiştirmeli bir adresleme modu kullanan 32 bit anlık ve bir bellek işleneni ekleyebilir. (SnB ve sonrasında, yalnızca tek kayıt adresleme modları, ALU işlemleriyle mikro sigortalanabilir).
uop'lar çok büyüktür ve sabit genişlikli ARM komutlarına çok benzemez. Sabit genişlikte bir 32bit komut seti bir seferde yalnızca 16 bit anında yükleyebilir, bu nedenle 32 bitlik bir adresin yüklenmesi anında düşük-yarı / yük-anında-yük çifti gerektirir. x86'nın bunu yapması gerekmez, bu da, sabitleri yazmaçlarda tutma yeteneğini sınırlayan yalnızca 15 GP kaydı ile korkunç olmamasına yardımcı olur. (15, 7 kayıt üzerinde büyük bir yardımdır, ancak tekrar 31'e ikiye katlamak çok daha az yardımcı olur, sanırım bazı simülasyonlar bulunur. RSP genellikle genel amaçlı değildir, bu nedenle daha çok 15 GP kaydı ve bir yığın gibidir.)
TL; DR özeti:
Her neyse, bu cevap "x86 komut seti, x86 komutlarını hızlı bir şekilde çalıştırması gereken bir CPU'yu programlamanın muhtemelen en iyi yoludur" şeklinde özetlenebilir, ancak umarız bunun nedenlerine biraz ışık tutacaktır.
Ön uç ve arka uçtaki dahili uop biçimleri
Ön uç ve arka uç uop formatlarının Intel CPU'larda neyi temsil edebileceğine ilişkin bir farklılık durumu için Mikro füzyon ve adresleme modlarına da bakın .
Dipnot 1 : Mikrokod tarafından geçici olarak kullanılmak üzere bazı "gizli" kayıtlar vardır. Bu yazmaçlar, tıpkı x86 mimari kayıtları gibi yeniden adlandırılır, böylece çoklu-uop komutları sıra dışı çalışabilir.
Örneğin xchg eax, ecx
, Intel CPU'larda 3 uops ( neden? ) olarak kod çözer ve en iyi tahminimiz bunların MOV benzeri uopslar olduğudur tmp = eax; ecx=eax ; eax=tmp;
. Bu sırayla, çünkü dst-> src yönünün gecikmesini ~ 1 döngüde ölçüyorum, diğer yol için 2'ye karşılık. Ve bu hareketler normal mov
talimatlar gibi değil ; sıfır gecikmeli hareket eliminasyonu için aday gibi görünmüyorlar.
PRF boyutunu deneysel olarak ölçmeye çalışmak ve gizli kayıtlar dahil mimari durumu tutmak için kullanılan fiziksel kayıtları hesaba katmak zorunda kalmaktan bahsedilmesi için http://blog.stuffedcow.net/2013/05/measuring-rob-capacity/ adresine de bakın .
Kod çözücülerden sonraki ön uçta, ancak kayıtları fiziksel kayıt dosyasına yeniden adlandıran düzenleme / yeniden adlandırma aşamasından önce, dahili uop formatı, x86 kayıt numaralarına benzer kayıt numaraları kullanır, ancak bu gizli kayıtları adreslemek için yer vardır.
Uop formatı, sıra dışı çekirdek (ROB ve RS) içinde biraz farklıdır, yani arka uç (yayınlama / yeniden adlandırma aşamasından sonra). İnt / FP fiziksel kayıt dosyalarının her birinin Haswell'de 168 girişi vardır , bu nedenle bir uop'taki her kayıt alanının bu kadarını ele alacak kadar geniş olması gerekir.
Yeniden adlandırıcı donanımda bulunduğundan, statik olarak programlanmış talimatları doğrudan arka uca beslemek yerine onu kullanmamız muhtemelen daha iyi olacaktır. Böylece, x86 mimari kayıtları + mikrokod geçici kayıtları kadar büyük bir kayıt kümesiyle çalışabilirdik, bundan daha fazlası değil.
Arka uç, WAW / WAR tehlikelerini önleyen bir ön uç yeniden adlandırıcıyla çalışmak üzere tasarlanmıştır, bu nedenle istesek bile sıralı bir CPU gibi kullanamazdık. Bu bağımlılıkları tespit etmek için kilitlere sahip değildir; sorun / yeniden adlandırma ile işlenir.
Sorun / yeniden adlandırma aşamasının (modern Intel ardışık düzenlerindeki en dar nokta, örneğin Skylake'de 4 genişliğe karşı 4 ALU + 2 yük + 1 mağaza bağlantı noktasında) darboğaz olmadan arka uca destek verebilirsek, düzgün olabilir. arka uç). Ancak bunu yaptıysanız, kaydı yeniden kullanmaktan kaçınmak için statik olarak kod programlayabileceğinizi ve bir önbellek kaçırma bir yükü uzun süre durdurduysa hala gerekli olan bir sonuca adım atacağınızı sanmıyorum.
Bu yüzden sorun / yeniden adlandırma aşamasına hemen hemen uop önbelleğini veya IDQ'yu değil, yalnızca kod çözmeyi atlayarak beslememiz gerekiyor. Sonra mantıklı tehlike tespiti ile normal OoO exec elde ederiz. Kayıt tahsis tablosu yalnızca 16 + birkaç tamsayı kaydını 168 girişli tamsayı PRF'ye yeniden adlandırmak için tasarlanmıştır. HW'nin daha büyük bir mantıksal yazmaç setini aynı sayıda fiziksel kayıt üzerine yeniden adlandırmasını bekleyemezdik; bu daha büyük bir RAT alır.