X86 neden çirkin? Neden diğerlerine kıyasla daha aşağı kabul ediliyor? [kapalı]


105

Son zamanlarda bazı SO arşivlerini okudum ve x86 mimarisine karşı ifadelerle karşılaştım.

ve gibi daha birçok yorum

Aramayı denedim ama herhangi bir neden bulamadım. Muhtemelen x86'yı kötü bulmuyorum çünkü aşina olduğum tek mimari bu.

Birisi bana x86'yı diğerlerine kıyasla çirkin / kötü / aşağı olarak düşünmem için nedenler verebilir mi?


1
Şimdiye kadarki cevaplara dayanarak S&A ile gidiyorum, ancak CISC'nin m68k komut seti için bir sorun olmadığını not edeceğim. x86 olduğu gibi ve onu saklayabilirsiniz.
dmckee --- eski moderatör kedicik

"S&A" nedir? "CISC, m68k komut seti için sorun değil." -- Neden olmasın?
pençeler

5
Motorala 68000 serisi yongalar oldukça CISC mimarisine sahiptir, ancak tek tip, oldukça ortogonal ve çok kolay komut setine sahiptirler. Neden x86'dan fark var? Bilmiyorum. Ancak , çipteki karmaşıklık ile komut setindeki karmaşıklık arasında (yani bir montaj programcısının gördüğü arabirimde) büyük bir fark olduğunu unutmayın .
dmckee --- eski moderatör kedicik

4
Çok ilginç bir soru için +1.
Turing

1
Burada, CISC ve RISC tasarımlarına neyin yol açtığına dair iyi bir tartışmanın yer aldığı, farklı işlemcilerin enerji verimliliği üzerine yapılan son çalışma. extremetech.com/extreme/…

Yanıtlar:


93

Bunun birkaç olası nedeni:

  1. x86 nispeten eski ISA (kendi atalarıdır sonuçta 8086s idi)
  2. x86, birkaç kez önemli ölçüde gelişmiştir, ancak eski ikili dosyalar ile geriye dönük uyumluluğu korumak için donanım gereklidir. Örneğin, modern x86 donanımı hala yerel olarak 16 bit kod çalıştırma desteği içerir. Ek olarak, gerçek mod, korumalı mod, sanal 8086 modu ve (amd64) uzun mod gibi eski kodun aynı işlemci üzerinde birlikte çalışmasına izin vermek için birkaç bellek adresleme modeli mevcuttur. Bu bazıları için kafa karıştırıcı olabilir.
  3. x86 bir CISC makinesidir. Uzun bir süre için bu, MIPS veya ARM gibi RISC makinelerinden daha yavaş olduğu anlamına geliyordu, çünkü talimatlarda veri karşılıklı bağımlılığı ve komut düzeyi paralelliğinin çoğu biçiminin uygulanmasını zorlaştıran işaretler var. Modern uygulamalar, bu tür optimizasyonların donanımda uygulanmasını pratik hale getirmek için x86 talimatlarını kapakların altındaki " mikro işlem " adı verilen RISC benzeri talimatlara çevirir .
  4. Bazı açılardan x86 daha aşağı değil, sadece farklı. Örneğin, girdi / çıktı, mimarilerin büyük çoğunluğunda bellek eşlemesi olarak işlenir, ancak x86'da değil. (Not: Modern x86 makineleri tipik olarak bir tür DMA desteğine sahiptir ve bellek eşleme yoluyla diğer donanımlarla iletişim kurar; ancak ISA'da hala INve gibi G / Ç talimatları vardır OUT)
  5. X86 ISA'da çok az sayıda mimari kayıt vardır ve bu da programları, aksi takdirde gerekenden daha sık bellek içinde dönmeye zorlayabilir. Bunu yapmak için ihtiyaç duyulan ekstra talimatlar, verimli mağaza yönlendirme olmasına rağmen, faydalı işler için harcanabilecek yürütme kaynaklarını alır.gecikmeyi düşük tutar. Kayıt defteri büyük bir fiziksel kayıt dosyası üzerine yeniden adlandırma ile modern uygulamalar birçok talimatı çalışır durumda tutabilir, ancak mimari kayıtların eksikliği hala 32 bit x86 için önemli bir zayıflıktı. x86-64'ün 8'den 16 tamsayıya ve vektör yazmaçlarına artışı, 64 bit koddaki en büyük faktörlerden biridir, her bir yazmacın artan genişliği değil, 32-bit'ten daha hızlıdır (daha verimli kayıt arama ABI ile birlikte). 16'dan 32 tamsayı kaydına bir artış daha fazla yardımcı olabilir, ancak bu kadar değil. (AVX512, 32 vektör yazmacına yükselir, çünkü kayan noktalı kod daha yüksek gecikmeye sahiptir ve genellikle daha fazla sabit gerektirir.) (Açıklamaya bakın )
  6. x86 derleme kodu karmaşıktır çünkü x86 birçok özelliğe sahip karmaşık bir mimaridir. Tipik bir MIPS makinesi için bir talimat listesi, tek bir harf boyutlu kağıt parçasına sığar. X86 için eşdeğer listeleme birkaç sayfayı doldurur ve talimatlar daha fazlasını yapar, bu nedenle genellikle ne yaptıklarına dair bir listenin sağlayabileceğinden daha büyük bir açıklamaya ihtiyacınız olur. Örneğin, MOVSBtalimatın ne yaptığını açıklamak için nispeten büyük bir C kodu bloğuna ihtiyacı vardır:

    if (DF==0) 
      *(byte*)DI++ = *(byte*)SI++; 
    else 
      *(byte*)DI-- = *(byte*)SI--;
    

    Bu, her biri bir RISC makinesinde ayrı talimatlar olan bir yükleme, bir depolama ve iki toplama veya çıkarma (bir işaret girişi tarafından kontrol edilir) yapan tek bir talimattır.

    MIPS (ve benzer mimariler) basitliği onları üstün kılmazken, assembler sınıfına giriş öğretmek için daha basit bir ISA ile başlamak mantıklıdır . Bazı montaj sınıfları , gerçek kullanım için kullanışlı olmama noktasının ötesinde basitleştirilen y86 adında ultra basitleştirilmiş bir x86 alt kümesini öğretir (örneğin, kaydırma talimatları yok) veya bazıları yalnızca temel x86 komutlarını öğretir.

  7. X86, talimatların ayrıştırılmasına göre donanım karmaşıklığı ekleyen değişken uzunluklu işlem kodları kullanır. Modern çağda bu maliyet, CPU'lar ham hesaplamaya göre bellek bant genişliğiyle gittikçe daha fazla sınırlı hale geldikçe, giderek azalmaktadır, ancak birçok "x86 dayatma" makalesi ve davranışı, bu maliyetin nispeten çok daha yüksek olduğu bir çağdan gelmektedir.
    2016 Güncellemesi: Anandtech, x64 ve AArch64 altındaki işlem kodu boyutlarıyla ilgili bir tartışma yayınladı .

DÜZENLEME: Bunun x86'ya vurulması gerekmiyor ! Parti. Sorunun söylendiği şekilde düşünüldüğünde, biraz dayak atmaktan başka seçeneğim yoktu. Ancak (1) dışında, tüm bunlar iyi nedenlerle yapıldı (yorumlara bakınız). Intel tasarımcıları aptal değil - mimarileriyle bazı şeyler başarmak istediler ve bunlar, bunları gerçeğe dönüştürmek için ödemeleri gereken vergilerden bazıları.


17
Bu bir değiş tokuş. İkili boyutun daha küçük olması bir güçtür, ancak bu talimatlar için bir ayrıştırıcı uygulamak için çok karmaşık donanıma sahip olmanız gerektiğinden bir zayıflıktır. Talimatların büyük çoğunluğu zaten aynı boyuttadır - x86'daki değişken uzunluktaki işlem kodlarının çoğu, özellik eklemeye karar vermeleri ve birlikte çalışmak zorunda kaldıkları bit sayısında istediklerini temsil edemediklerini fark etmeleridir. . İnsanların büyük çoğunluğu, donanım karmaşıklığı veya güç tüketimi kadar ikili boyutla ilgilenmez.
Billy ONeal

8
@Joey Adams: x86'nın değişken uzunluk talimatlarını ARM'ın Başparmak Modu ( en.wikipedia.org/wiki/ARM_architecture#Thumb ) ile karşılaştırın. Başparmak Modu, ARM için önemli ölçüde daha küçük nesne koduyla sonuçlanır çünkü daha kısa talimatlar doğrudan normal talimatlarla eşleşir. Ancak daha büyük talimatlarla daha küçük talimatlar arasında 1: 1 eşleme olduğu için, ayrıştırma donanımının uygulanması kolaydır. X86'nın değişken uzunluktaki talimatları bu avantajlara sahip değil çünkü ilk etapta bu şekilde tasarlanmamışlardı.
Billy ONeal

7
(6) Her işlem kodunun her program tarafından kullanılması gerekmez, ancak kahretsin, SSE3'e ihtiyacım olduğunda, buna sahip olduğum için memnunum.
Chris K

4
@Chris Kaminski: Donanımı nasıl etkilemiyor? Elbette, modern, tam boyutlu bir bilgisayarda kimse umursamayacak, ancak cep telefonu gibi bir şey yapıyorsam, güç tüketimini neredeyse her şeyden daha çok önemsiyorum. Değişken uzunluklu işlem kodları yürütme süresini artırmaz, ancak kod çözme donanımının çalışması için yine de güç gerekir.
Billy ONeal

5
X86 komut setini bu kadar çirkin yapan şeylerden biri, çünkü bunun bir akümülatör mü yoksa kayıt dosyası tabanlı bir mimari mi olduğuna karar veremiyor (bu çoğunlukla 386 ile sabitlenmişti, bu da komut setini çok daha ortogonal hale getiriyordu) 68k hayranlarının size söylediklerinden bağımsız olarak).
ninjalj

25

Aklımda x86'ya karşı ana darbe CISC kökenleri - komut seti birçok örtük karşılıklı bağımlılık içeriyor. Bu karşılıklı bağımlılıklar, çip üzerinde talimatın yeniden sıralanması gibi şeyler yapmayı zorlaştırır, çünkü bu karşılıklı bağımlılıkların yapıları ve anlambilimlerinin her bir talimat için korunması gerekir.

Örneğin, x86 tamsayı toplama ve çıkarma komutlarının çoğu bayrak kaydını değiştirir. Bir toplama veya çıkarma gerçekleştirdikten sonra, sonraki işlem genellikle taşma, işaret biti, vb. İçin işaretler kaydına bakmaktır. Bundan sonra başka bir ekleme varsa, 2. eklemeyi çalıştırmaya başlamanın güvenli olup olmadığını söylemek çok zordur. 1. ekin sonucu bilinmeden önce.

Bir RISC mimarisinde, add komutu, giriş işlenenlerini ve çıkış yazmaçlarını belirtir ve işlemle ilgili her şey yalnızca bu yazmaçlar kullanılarak gerçekleşir. Bu, birbirine yakın olan ekleme işlemlerinin ayrıştırılmasını çok daha kolay hale getirir çünkü her şeyi sıraya koyup tek bir dosyayı yürütmeye zorlayan hiçbir çiçeklenme bayrak kaydı yoktur.

MIPS tarzı bir RISC tasarımı olan DEC Alpha AXP yongası, mevcut talimatlarda acı verici bir şekilde spartan idi, ancak talimat seti, talimatlar arası örtük yazmaç bağımlılıklarından kaçınmak için tasarlandı. Donanım tanımlı yığın kaydı yoktu. Donanım tanımlı bayrak kaydı yoktu. Yönerge işaretçisi bile işletim sistemi tanımlıydı - arayan kişiye geri dönmek istiyorsanız, arayanın size hangi adrese döneceğinizi nasıl bildireceğini hesaplamanız gerekiyordu. Bu genellikle işletim sistemi çağrı kuralı tarafından tanımlanmıştır. X86'da ise yonga donanımı tarafından tanımlanıyor.

Her neyse, 3 veya 4 nesilden fazla Alpha AXP yonga tasarımı, donanım, 32 int yazmaç ve 32 değişken yazmaçlı spartan komut setinin gerçek bir uygulaması olmaktan, 80 dahili yazmaç, yazmaç yeniden adlandırma, büyük ölçüde sıra dışı yürütme motoruna dönüştü sonuç iletme (önceki bir talimatın sonucunun değere bağlı olan sonraki bir talimata yönlendirildiği) ve her türlü çılgın ve çılgın performans artırıcı. Ve tüm bu çanlar ve ıslıklarla, AXP yonga kalıbı hala o zamanın karşılaştırılabilir Pentium yonga kalıbından önemli ölçüde daha küçüktü ve AXP çok daha hızlıydı.

X86 soy ağacındaki şeyleri artıran bu tür performans patlamalarını görmezsiniz, çünkü x86 komut setinin karmaşıklığı birçok tür yürütme optimizasyonunu imkansız olmasa da çok pahalı hale getirir. Intel'in dehası, artık donanımda x86 komut setini uygulamaktan vazgeçmek oldu - tüm modern x86 yongaları, aslında x86 komutlarını belirli bir dereceye kadar yorumlayan ve bunları orijinal x86'nın tüm anlamlarını koruyan dahili mikrokoda dönüştüren RISC çekirdekleridir. talimat, ancak bu RISC'nin biraz çalışmasına ve mikrokod üzerinden diğer optimizasyonlara izin verir.

Çok sayıda x86 assembler yazdım ve CISC köklerinin rahatlığını tam olarak takdir edebiliyorum. Ancak Alpha AXP assembler'ı yazmak için biraz zaman harcayana kadar x86'nın ne kadar karmaşık olduğunu tam olarak anlamadım. AXP'nin sadeliği ve tekdüzeliği beni şaşkına çevirdi. Farklılıklar çok büyük ve derin.


6
M68k'yi açıklayamadığınız sürece , CISC'nin tek başına çiğnenmesini dinleyeceğim .
dmckee --- eski moderatör kedicik

2
M68k'ye aşina değilim, bu yüzden eleştiremiyorum.
dthorpe

4
Bu cevabın olumsuz oy vermek için yeterince kötü olduğunu düşünmüyorum, ancak tüm "RISC CISC'den daha küçük ve daha hızlıdır" argümanının modern çağla pek alakalı olmadığını düşünüyorum. Elbette, AXP zamanı geldiğinde çok daha hızlı olabilirdi, ancak gerçek şu ki, konu performans söz konusu olduğunda modern RISC'ler ve modern CISC'ler hemen hemen aynı. Cevabımda söylediğim gibi, x86 kod çözme için hafif güç cezası, x86'yı cep telefonu gibi bir şey için kullanmama nedenidir, ancak bu tam boyutlu bir masaüstü veya dizüstü bilgisayar için küçük bir argüman.
Billy ONeal

4
@Billy: boyut, kod boyutundan veya komut boyutundan daha fazlasıdır. Intel, tüm bu özel talimatlar için donanım mantığını, kaputun altındaki RISC mikrokod çekirdeğini uygulamak için yonga yüzey alanında büyük bir ceza ödüyor. Kalıbın boyutu, üretim maliyetini doğrudan etkiler, bu nedenle modern sistem tasarımlarında hala geçerli bir sorundur.
dthorpe

1
@dthorpe: Yazdıklarınızın hepsi değilse de çoğuna katılmıyorum. 8086'dan beri, addbirbiri ardına yürütmenin güvenli olup olmadığı konusunda endişelenmenize gerek yoktu add. Kurallar açık. Ayrıca talimatların yeniden sıralanmasıyla uğraşmanıza da gerek yoktur. 90'ların ortalarından Pentium Pro'dan beri CPU bunu sizin için yapıyor. Bahsettiğiniz şey 20 yıl önce bir sorun olabilirdi, ancak bunu günümüzde x86 mimarisine karşı tutmak için herhangi bir neden göremiyorum.
Nathan Fellman

21

X86 mimarisi 8008 mikroişlemci ve akrabalarının tasarımına dayanmaktadır. Bu CPU'lar belleğin yavaş olduğu bir zamanda tasarlandı ve bunu CPU kalıbı üzerinde yapabilseydiniz, genellikle çok daha hızlıydı. Bununla birlikte, CPU kalıp alanı da pahalıydı. Bu iki neden, neden özel amaçlara sahip olma eğiliminde olan az sayıda yazmaç ve her türden aldatma ve sınırlama içeren karmaşık bir talimat seti olmasıdır.

Aynı döneme ait diğer işlemciler de (örneğin, 6502 ailesi) benzer sınırlamalara ve tuhaflıklara sahiptir. İlginç bir şekilde, hem 8008 serisi hem de 6502 serisi gömülü kontrolörler olarak tasarlandı. O zamanlar bile, gömülü kontrolörlerin assembler'da programlanması ve birçok yönden derleyici yazıcıdan ziyade assembly programcısına hitap etmesi bekleniyordu. (Derleyici yazısına hitap ettiğinizde neler olduğunu görmek için VAX çipine bakın.) Tasarımcılar bunların genel amaçlı bilgisayar platformları olmasını beklemiyorlardı; POWER mimarisinin öncülleri gibi şeyler bunun içindi. Ev Bilgisayarı devrimi bunu değiştirdi elbette.


4
Aslında konuyla ilgili geçmişe sahip gibi görünen birinden burada tek cevap +1.
Billy ONeal

3
Hafıza her zaman yavaş olmuştur. Muhtemelen bugün (nispeten konuşursak), 1982'de Z80'ler ve CP / M ile başladığımdan daha yavaştır. Yok olma, evrimin tek yolu değildir, çünkü yok oluşla birlikte belirli evrimsel yön durur. X86'nın 28 yılında (şimdiye kadarki varlığı) iyi bir şekilde adapte olduğunu söyleyebilirim.
Olof Forshell

4
Bellek hızları 8086 civarında CPU'larla kısa bir süreliğine eşitliğe ulaştı. Texas Instruments'ın 9900 modeli, yalnızca bu olduğu için çalışan bir tasarıma sahip. Ama sonra CPU tekrar öne geçti ve orada kaldı. Ancak şimdi, bunu yönetmeye yardımcı olacak önbellekler var.
staticsan

3
@Olof Forshell: 8080 montaj kodunun 8086 koduna çevrilebilmesi için assembler uyumluydu. Bu bakış açısına göre, 8080'i 8008 artı uzantılar olarak görebileceğiniz gibi, 8080 artı uzantılardı.
David Thornley

3
@Olof Forshell: 8086 bunun gerçekleşmesi için tasarlanmış olması dışında. Bu, 8080'in bir uzantısıydı ve çoğu (muhtemelen tümü) 8080 talimatı, açıkça benzer anlambilimle bire bir eşlenmişti. Hangi yöne itmek isterseniz isteyin, IBM 360 mimarisi için bu doğru değildir.
David Thornley

13

Burada birkaç ek yönüm var:

"A = b / c" x86 işleminin bunu şu şekilde uygulayacağını düşünün:

  mov eax,b
  xor edx,edx
  div dword ptr c
  mov a,eax

Div talimatının ek bir bonusu olarak edx kalanı içerecektir.

Bir RISC işlemcisi önce b ve c adreslerinin yüklenmesini, bellekten b ve c'nin kayıtlara yüklenmesini, bölme işleminin yapılmasını ve a adresinin yüklenmesini ve ardından sonucun depolanmasını gerektirir. Dst, src sözdizimi:

  mov r5,addr b
  mov r5,[r5]
  mov r6,addr c
  mov r6,[r6]
  div r7,r5,r6
  mov r5,addr a
  mov [r5],r7

Burada genellikle bir kalıntı olmayacak.

Herhangi bir değişken işaretçiler aracılığıyla yüklenecekse, her iki sekans da uzayabilir, ancak bu RISC için daha az olasıdır çünkü başka bir kayıtta bir veya daha fazla işaretçi zaten yüklü olabilir. x86'da daha az kayıt vardır, bu nedenle işaretçinin bunlardan birinde olma olasılığı daha düşüktür.

Lehte ve aleyhte olanlar:

RISC komutları, komut zamanlamasını iyileştirmek için çevreleyen kodla karıştırılabilir, bu, bunun yerine CPU'nun içinde bu işi yapan (sıraya bağlı olarak az çok iyi) x86 ile daha az olasıdır. Yukarıdaki RISC dizisi, 32 bit mimaride tipik olarak 28 bayt uzunluğunda (her biri 32 bit / 4 bayt genişliğinde 7 komut) olacaktır. Bu, talimatı getirirken yonga dışı belleğin daha fazla çalışmasına neden olur (yedi getirme). Daha yoğun olan x86 dizisi daha az komut içerir ve genişlikleri değişse de, muhtemelen orada da ortalama 4 bayt / talimata bakıyorsunuzdur. Bu yedi getirmeyi hızlandırmak için talimat önbellekleriniz olsa bile, x86'ya kıyasla telafi etmek için başka bir yerde üç tane açığınız olacağı anlamına gelir.

Kaydedilecek / geri yüklenecek daha az kayıt içeren x86 mimarisi, muhtemelen iş parçacığı anahtarları yapacağı ve kesintileri RISC'den daha hızlı işleyeceği anlamına gelir. Kaydetmek ve geri yüklemek için daha fazla kayıt, kesintiler için daha fazla geçici RAM yığın alanı ve iş parçacığı durumlarını depolamak için daha kalıcı yığın alanı gerektirir. Bu özellikler, x86'yı saf RTOS çalıştırmak için daha iyi bir aday haline getirmelidir.

Daha kişisel bir not olarak, RISC derlemesini yazmayı x86'ya göre daha zor buluyorum. Bunu, RISC rutinini C'de yazarak, üretilen kodu derleyerek ve değiştirerek çözüyorum. Bu, kod üretimi açısından daha verimlidir ve yürütme açısından muhtemelen daha az verimlidir. İzlenecek tüm bu 32 kayıt. X86 ile durum tam tersidir: "gerçek" adlara sahip 6-8 kayıt, sorunu daha yönetilebilir hale getirir ve üretilen kodun beklendiği gibi çalışacağına dair daha fazla güven verir.

Çirkin? Bu, bakanın gözündedir. "Farklı" yı tercih ederim.


Örneklerimdeki a, b ve c anlık değerler olarak değil belleğe dayalı değişkenler olarak görülmelidir.
Olof Forshell

... "dword ptr", boyutu bilinmeyen bir değişkenin boyutunu belirtmek için kullanılır, örneğin, basitçe harici olarak bildirilmişse veya tembel olmuşsanız.
Olof Forshell

2
Bu, ilk önce C ile yazma ve sonra derleyiciye damıtma önerisini ilk kez duymuyorum. Bu kesinlikle yardımcı oluyor
Joe Plante

İlk zamanlarda tüm işlemciler RISC idi. CISC, ÇOK yavaş demir çekirdek bellek sistemleri için bir azaltma stratejisi olarak ortaya çıktı, bu nedenle CISC, daha az, daha güçlü talimatlarla, bellek alt sistemine daha az baskı uyguladı ve bant genişliğini daha iyi kullandı. Aynı şekilde, yazmaçlar başlangıçta yonga üzerinde, biriktirme yapmak için CPU içi bellek konumları olarak düşünülüyordu. Bir RISC makinesini en son ciddi şekilde kıyasladığımda 1993 - SPARC ve HP Prisim oldu. SPARC, genel olarak korkunçtu. Prisim, add / sub / mul'da 486'dan 20 kata kadar daha hızlıydı, ancak transandantallarda emildi. CISC daha iyidir.

@OlofForshell Diyorsun there typically won't be a reminderama wiki mipslerde olduğunu söylüyor: en.wikipedia.org/wiki/MIPS_instruction_set#Integer
Alex Zhukovskiy

10

Bu sorunun yanlış bir varsayımı olduğunu düşünüyorum. X86'ya çirkin diyenler sadece RISC takıntılı akademisyenlerdir. Gerçekte, x86 ISA, RISC ISA'larda 5-6 komut alan tek bir komut işleminde gerçekleştirebilir. RISC hayranları, modern x86 CPU'ların bu "karmaşık" talimatları mikrooplara böldüğüne karşı çıkabilir; ancak:

  1. Çoğu durumda bu sadece kısmen doğrudur veya hiç doğru değildir. X86'daki en yararlı "karmaşık" talimatlar, mov %eax, 0x1c(%esp,%edi,4)örneğin adresleme modları gibi şeylerdir ve bunlar bozulmaz.
  2. Modern makinelerde genellikle daha önemli olan, harcanan döngü sayısı değil (çünkü çoğu görev cpu'ya bağlı değildir), kodun talimat önbelleği etkisidir. 5-6 sabit boyutlu (genellikle 32bit) talimatlar, önbelleği, nadiren 5 bayttan fazla olan birden fazla karmaşık talimatı etkiler.

x86, yaklaşık 10-15 yıl önce RISC'nin tüm iyi yönlerini gerçekten özümsedi ve RISC'nin kalan nitelikleri (aslında tanımlayıcı olan - minimum komut seti) zararlı ve istenmeyen.

CPU üretiminin maliyeti ve karmaşıklığı ve enerji gereksinimleri bir yana, x86 en iyi ISA'dır . Size aksini söyleyen biri, ideolojinin veya gündemin akıl yürütmelerinin önüne geçmesine izin veriyor.

Öte yandan, CPU'nun maliyetinin önemli olduğu gömülü cihazları veya enerji tüketiminin önemli olduğu gömülü / mobil cihazları hedefliyorsanız, ARM veya MIPS muhtemelen daha mantıklıdır. Yine de, kolayca 3-4 kat daha büyük olan kodu işlemek için gereken ekstra ram ve ikili boyutla uğraşmanız gerekecek ve performansa yaklaşamayacağınızı unutmayın. Bunun önemli olup olmadığı, üzerinde ne çalıştıracağınıza bağlıdır.


3
Enerji tüketiminin en önemli sorun olduğu yerde, ARM veya MIPS muhtemelen daha mantıklıdır ... bu nedenle , ARM veya MIPS'nin daha anlamlı olduğu en az bir özellik varsa, x86'yı mutlaka en iyi ISA yapmaz mı?
Shahbaz

Bu nedenle, "maliyet ve enerji gereksinimleri bir yana" "en iyiyi" nitelendirdim.
R .. GitHub DUR YARDIMCI ICE

1
Bence Intel'in CPU hızını düşürmesi ve daha küçük kalıp boyutları güç farkını büyük ölçüde ortadan kaldırdı. 64k L1 ve 1MB L2 önbelleğe sahip yeni Celeron çift 64-bit CPU 7.5 watt'lık bir çiptir. Bu benim "Starbucks" mekân makinem ve pil ömrü gülünç derecede uzun ve bir P6 makinesinin etrafında halkalar dolaşacak. Çoğunlukla kayan nokta hesaplamaları yapan biri olarak uzun zaman önce RISC'den vazgeçtim. Sadece sürünüyor. Özellikle SPARC acımasızca buzuldu. RISC'nin neden berbat olduğunun mükemmel bir örneği Intel i860 CPU idi. Intel bir daha oraya gitmedi.

@RocketRoy: 7,5 watt, 7/24 çalışan (ve her zaman yararlı hesaplamalar yapmayan) veya 3.7v / 2000mAh pille çalışan bir cihaz için gerçekten kabul edilemez.
R .. GitHub BUZA YARDIM ETMEYİ DURDUR

2
@RocketRoy "Intel i860 CPU. Intel bir daha ORAYA gitmedi." Küçük bir araştırmadan sonra, i860 Itanium'a çok benziyor: VLIW, derleyici sıralı talimat paralelliği ....
Jonathon Reinhart

9

x86 assembler dili o kadar da kötü değil. Makine koduna ulaştığınızda gerçekten çirkinleşmeye başlar. Komut kodlamaları, adresleme modları, vb. Çoğu RISC CPU'larından çok daha karmaşıktır. Ve geriye dönük uyumluluk amacıyla yerleşik ekstra eğlence var - yalnızca işlemci belirli bir durumda olduğunda devreye giren şeyler.

Örneğin 16 bitlik modlarda adresleme düpedüz tuhaf görünebilir; için bir adresleme modu var [BX+SI], ancak biri için değil [AX+BX]. Bunun gibi şeyler, ihtiyaç duyduğunuz şekilde kullanabileceğiniz bir kayıt defterinde değerinizin olmasını sağlamanız gerektiğinden, kayıt kullanımını karmaşıklaştırma eğilimindedir.

(Neyse ki, 32 bit modu çok daha mantıklıdır (yine de bazen kendisi biraz tuhaftır - örneğin bölümleme) ve 16 bit x86 kodu artık önyükleme yükleyicileri ve bazı gömülü ortamlar dışında büyük ölçüde önemsizdir.)

Intel'in x86'yı en iyi işlemci yapmaya çalıştığı eski günlerden kalanlar da var. Aslında hiç kimsenin yapmadığı görevleri yerine getiren birkaç bayt uzunluğundaki talimatlar, çünkü açıkçası çok yavaş ya da karmaşıktılar. ENTER ve LOOP talimatları , iki örnek için - C yığını çerçeve kodunun çoğu derleyici için "push ebp; mov ebp, esp" gibidir ve "enter" değildir.


2
Bazı işlemcilerde "push / mov" daha hızlı olduğu için "enter" ve "push / mov" sorununun ortaya çıktığına inanıyorum. Bazı işlemcilerde "gir" daha hızlıdır. C'est la vie.
Dietrich Epp

4
X86 tabanlı bir makineye zorlandığımda ve ona bakmaya başladığımda (m68k geçmişine sahipken), asm programlamayı sinir bozucu hissetmeye başladım ... sanki C gibi bir dille programlamayı öğrenmişim gibi ve sonra asm ile iletişim kurmak zorunda ... ifade, kolaylık, netlik, "tutarlılık", "sezgisellik" gücünü kaybettiğinizi "hissediyorsunuz". x86 ile programlamaya başlamış olsaydım eminim o kadar kötü değil ... belki ... ben de MMIX ve MIPS yaptım ve "asm lang" x86'dan çok daha iyi (eğer bu Q için doğru
PoV

Adresleme modu sorunu 80386'da düzeltildi. Yalnızca 16 bit kodun sınırlı adresleme modu vardır, 32 bit kod çok daha iyidir. 32 bit adresleme modlarını özel bir önek kullanarak 16 bit kodda veya tersi şekilde alabilirsiniz.
fuz

@FUZxxl: Evet ... Muhtemelen çirkinliğin çoğunlukla 16 bitlik kodla sınırlı olduğunu söylemeliydim . Sabit (sanırım). :)
cHao

Algılanan hoşnutsuzluk çoğunlukla 8086'nın kayıtlarının genel amaçlı kayıtlar olduğu yanılgısından kaynaklanmaktadır; bu yanlış. Her birinin özel bir amacı vardır ve eğer amaçlarına bağlı kalmazsanız, kötü bir zaman geçireceksiniz.
fuz

3

Uzman değilim, ancak insanların hoşlanmamasının birçok özelliği iyi performans göstermesinin nedenleri olabilir. Birkaç yıl önce, yazmaçlara (yığın yerine), kayıt çerçevelerine vb. Sahip olmak, mimarinin insanlara daha basit görünmesini sağlamak için güzel çözümler olarak görülüyordu. Ancak günümüzde önemli olan önbellek performansı ve x86'nın değişken uzunluklu sözcükleri önbellekte daha fazla talimat depolamasına izin veriyor. Rakiplerin bir zamanlar çipin yarısını aldığına inandığım "talimat çözme" artık pek de öyle değil.

Paralelliğin günümüzde en önemli faktörlerden biri olduğunu düşünüyorum - en azından zaten kullanılabilecek kadar hızlı çalışan algoritmalar için. Yazılımda yüksek paralellik ifade etmek, donanımın bellek gecikmelerini amorti etmesine (veya genellikle tamamen gizlemesine) izin verir. Elbette, daha uzağa ulaşan mimari gelecek muhtemelen kuantum hesaplama gibi bir şeyde.

NVidia'dan Intel'in hatalarından birinin ikili formatları donanıma yakın tutmaları olduğunu duydum. CUDA'nın PTX'i bazı hızlı kayıt kullanım hesaplamaları (grafik renklendirme) yapar, böylece nVidia yığın makinesi yerine bir kayıt makinesi kullanabilir, ancak yine de tüm eski yazılımları bozmayan bir yükseltme yoluna sahiptir.


9
RISC, insan geliştiriciler düşünülerek tasarlanmamıştır. RISC'nin arkasındaki fikirlerden biri, yonganın karmaşıklığının bir kısmını derlemeyi yazan kişiye, ideal olarak derleyiciye aktarmaktı. Daha fazla kayıt, daha az bellek kullanımı ve talimatlar arasında daha az bağımlılık anlamına geliyordu, bu da daha derin işlem hatlarına ve daha yüksek performansa izin veriyordu. X86-64'ün x86'nın iki katı genel kayda sahip olduğunu ve bu tek başına önemli performans kazançlarından sorumlu olduğunu unutmayın. Ve çoğu x86 yongası üzerindeki talimatların kodu önbelleğe alınmadan önce çözülür, sonra değil (dolayısıyla boyutun burada önemi yoktur).
Dietrich Epp

3
@Dietrich Epp: Bu tamamen doğru değil. X86-64'ün ISA'da görülebilen daha fazla yazmaçları vardır, ancak modern x86 uygulamaları genellikle, yürütmeyi hızlandırmak için talep üzerine ISA'nın kayıtlarına eşlenen RISC tarzı bir kayıt dosyasına sahiptir.
Billy ONeal

"NVidia'dan Intel'in hatalarından birinin, ikili formatları donanıma yakın tutmaları olduğunu duydum." - Bunu ve CUDA'nın PTX bölümünü almadım.
pençeler

1
@Dietrech Epp: "Ve çoğu x86 yongasındaki talimatların kodu önbelleğe alınmadan önce çözülür, sonra değil" Bu doğru değil. Kodları çözülmeden önce önbelleğe alınırlar. Pentium 4'ün kod çözüldükten sonra önbelleğe alınan ek bir izleme önbelleği olduğuna inanıyorum, ancak bu artık durduruldu.
Nathan Fellman

bu doğru değil, en yeni "kumlu köprü" işlemcileri bir tür izleme önbelleği kullanıyor (pentium 4 için olduğu gibi, oh o eski çocuk: D), bu yüzden teknolojiler ortadan
kalkıyor

3

İnsanların daha önce bahsettiği nedenlerin yanı sıra:

  • x86-16, tek bir bellek konumunun 4096 farklı yolla adreslenmesine, RAM'i 1 MB ile sınırlandırmasına ve programcıları iki farklı boyutta işaretçi ile uğraşmaya zorlayan oldukça garip bir bellek adresleme şemasına sahipti . Neyse ki, 32-bite geçiş bu özelliği gereksiz hale getirdi, ancak x86 yongaları hala segment kayıtlarının temelini taşıyor.
  • Süre değil bir arıza x86 kendiliğinden x86 arama kuralları (MS-DOS herhangi derleyiciler ile gelmedi çünkü çoğunlukla) karmaşa ile bize bırakarak oldu MIPS gibi standardize edilmemiştir __cdecl, __stdcall, __fastcallvb

Hmm .. x86 rakiplerini düşündüğümde, MIPS'i düşünmüyorum. ARM veya PowerPC belki ....
Billy ONeal

@Billy: x86 sonsuza kadar ortalıkta. Bir zamanlar MIPS bir x86 rakibiydi. Hatırladığım kadarıyla x86, MIPS ile rekabet edebilecek bir seviyeye ulaşmak için işini bitirdi. (MIPS ve SPARC, iş istasyonu arenasında mücadele ederken.)
Shannon Kıdemliliği

@Shannon Kıdem: Bir şey bir zamanlar olduğu için olan bir şey anlamına gelmez.
Billy ONeal

2
@supercat: Düz x86-32 bellek modeli çağındaki insanların unutmaya meyilli oldukları şey, 16 bitin 64k bellek anlamına gelmesidir (matematik yapmaktan rahatsız olan herkes sihrin mümkün olmadığını, 8086'nın bir şüphesiz programcılar için çirkin ceza). 64.000'e ulaşmanın birkaç yolu var, ancak 8086 çözümü iyi bir uzlaşmaydı.
Olof Forshell

2
@OlofForshell: Sanırım pek çok insan 8086'nın 68000 kadar güzel olmadığı gerçeğinden şikayetçi oldu (16 MB doğrusal adresleme alanı ve 4 konser için açık bir yol vardı). Kesinlikle 32 bitlik bir işlemciye gitmek 64K'dan daha fazlasına erişimi kolaylaştıracaktır, ancak 8086, 8 bitlik 8080'den bir adım ötede olacak şekilde tasarlanmış 16 bitlik bir mimaridir. Intel'in sıçraması için hiçbir neden göremiyorum. doğrudan 8 bitten 32 bit'e.
supercat

3

X86'yı hedefleyen bir derleyici yazmaya çalışırsanız veya bir x86 makine öykünücüsü yazarsanız veya ISA'yı bir donanım tasarımında uygulamaya çalışsanız bile, cevabın bir kısmını alacağınızı düşünüyorum.

"X86 çirkin!" argümanlar, hala x86 derlemesini yazmanın MIPS'ten daha eğlenceli olduğunu düşünüyorum (örneğin) - ikincisi sadece sıkıcı. İnsanlardan çok derleyiciler için her zaman iyi olması amaçlanmıştır. Bir çipin, denerse derleyici yazarlara karşı daha düşmanca davranacağından emin değilim ...

Benim için en çirkin kısım, (gerçek mod) segmentasyonun çalışma şeklidir - herhangi bir fiziksel adresin 4096 segmenti vardır: ofset takma adları. Buna en son ne zaman ihtiyacın vardı? Segment parçası 32 bitlik bir adresin kesinlikle daha yüksek sıralı bitleri olsaydı işler çok daha kolay olurdu.


Eğer doğru PoV, insanların bu derlemede kod yazabilmesinin yolu ise, m68k çok daha komik ve insanlara x86'dan çok daha hoş (ki bu pek çok m68k programcısına o kadar "insan" görünmüyor).
ShinTakezou

Segment: ofset adresleme, CP / M - dünyası ile bir dereceye kadar uyumlu kalma girişimiydi. Şimdiye kadarki en kötü kararlardan biri.
Turing

@Turing Complete: segment: offset öncelikle CP / M dünyasıyla uyumlu kalma girişimi DEĞİLDİR. Kod, veri, yığın ve diğer bellek alanlarını farklı bölümlere yerleştirerek 16 bit işlemcinin 64 KBayttan daha fazlasını adreslemesine izin vermek için çok başarılı bir girişimdi.
Olof Forshell

1
Gerçekte, verileri ve yığını farklı segmentlere yerleştirmek C için tamamen yararsızdı; sadece asm için kullanılabilirdi. C'de, bir işaretçi statik, otomatik veya dinamik olarak ayrılmış depolama süresi olan verilere işaret edebilir, bu nedenle segmenti atlamanın bir yolu yoktur. Belki Pascal ya da Fortran ya da başka bir şey için yararlıydı, ama o zamanlar hâlihazırda baskın dil olan C için değildi ...
R .. GitHub BUZ YARDIMINI DURDUR

2
@Bernd: İş parçacığı yerel depolama için fs / gs'nin seçilmesinin nedeni, segment kayıtlarının bunun için iyi olması değil. Sadece x86 ciddi şekilde yazmaçlara aç kaldı ve bölüm yazmaçları kullanılmamıştı. İş parçacığı yapısına işaret eden genel amaçlı bir yazmaç da aynı şekilde çalışabilirdi ve aslında daha fazla yazmacı olan birçok RISC sistemi birini evre işaretçisi olarak kullanır.
R .. GitHub BUZA YARDIM ETMEYİ DURDUR

1
  1. x86, çok, çok sınırlı bir genel amaçlı kayıt kümesine sahiptir

  2. Etkili bir yükleme / depolama metodolojisi yerine en düşük seviyede (CISC cehennemi) çok verimsiz bir geliştirme tarzını teşvik eder

  3. Intel, düpedüz aptal segmenti / ofseti - modası geçmiş teknolojiyle (şu anda zaten!) Uyumlu kalmak için bellek adresleme modelini tanıtmak için korkunç bir karar verdi.

  4. Herkesin 32 bit gittiği bir zamanda, x86, yetersiz 16 bit (çoğu - 8088 - sadece 8 bit harici veri yollarıyla bile, ki bu daha da korkutucu!) Ana PC dünyasını geride tuttu!


Benim için (ve her nesil bilgisayarı geliştiricilerin bakış açısından gören bir DOS tecrübesiyim!) 3. nokta en kötüsüydü.

90'ların başlarında yaşadığımız şu durumu düşünün (ana akım!):

a) Eski nedenlerden dolayı çılgın sınırlamalara sahip bir işletim sistemi (640kB kolay erişilebilir RAM) - DOS

b) RAM açısından daha fazlasını yapabilen, ancak oyun vb. şeyler söz konusu olduğunda sınırlı olan ve dünyadaki en kararlı şey olmayan bir işletim sistemi uzantısı (Windows) (neyse ki bu daha sonra değişti, ama ben Burada 90'ların başlarından bahsediyorum)

c) Çoğu yazılım hala DOS'tu ve özel yazılımlar için sık sık önyükleme diskleri oluşturmak zorunda kaldık, çünkü bazı programların sevdiği, diğerlerinin nefret ettiği bu EMM386.exe vardı (özellikle oyuncular - ve ben o sırada bir AVID oyuncusuydum - ne olduğunu biliyorum buradan bahsediyorum)

d) MCGA 320x200x8 bit ile sınırlıydık (tamam, özel numaralarla biraz daha fazlası vardı, 360x480x8 mümkündü, ancak yalnızca çalışma zamanı kitaplığı desteği olmadan), diğer her şey dağınık ve korkunçtu ("VESA" - lol)

e) Ancak donanım açısından, birkaç megabayt RAM ve 1024x768'e kadar destekli VGA kartlara sahip 32 bit makinelerimiz vardı.

Bu kötü durumun nedeni nedir?

Intel'den basit bir tasarım kararı. Makine talimat seviyesi (ikili seviye DEĞİL!) Zaten ölmekte olan bir şeye uyumluluk, 8085 olduğunu düşünüyorum. Görünüşte alakasız olan diğer problemler (grafik modları, vb.) Teknik nedenlerle ve çok dar x86 platformunun getirdiği fikirli mimari.

Bugün durum farklı, ancak herhangi bir derleyici geliştiricisine veya x86 için derleyici arka uçları oluşturan kişilere sorun. Genel amaçlı kayıtların inanılmaz derecede az olması, korkunç bir performans katilinden başka bir şey değildir.


8086 bölümlü mimariyle ilgili tek büyük sorun, yalnızca bir adanmamış bölüm kaydı (ES) olması ve programlama dillerinin bununla etkili bir şekilde çalışmak üzere tasarlanmamasıydı. Kullandığı ölçeklenmiş adresleme stili, nesnelerin rastgele adreslerde başlamasını beklemeyen nesne yönelimli bir dilde çok iyi çalışacaktır (nesneleri paragraf sınırları üzerinde hizalarsa, nesne referanslarının yalnızca iki bayt olması gerekir. dört). İlk Macintosh kodunu PC koduyla karşılaştırırsanız, 8086 68000'e kıyasla oldukça iyi görünüyor.
supercat

@supercat: aslında, es kaydı bir şeye, yani depolama (movs, stos) veya tarama (cmps ve scas) gerektiren dizgi talimatlarına adanmıştı. Her bölüm kayıtlarından 64KiB adresleme verildiğinde, kod, veri ve yığın belleği (cs, ds, ss) dışındaki belleğe "eksik bağlantı" da sağlandı. Segment kayıtları, kayıtların 64Kib bellek bloklarının dışında adresleyemediğiniz bir tür bellek koruma şeması sağladı. X86'nın 16 bit mimarisi ve günün litografi kısıtlamaları göz önüne alındığında daha iyi bir çözüm öneriyorsunuz?
Olof Forshell

@OlofForshell: ES, dizgi talimatları için kullanıldı, ancak bunları kullanmayan kod için taahhüt edilmeyen bir kayıt olarak kullanılabilir. Seg-reg darboğazını çok fazla işlem kodu alanı gerektirmeden hafifletmenin bir yolu, aşağıdaki r / m-format talimatı için "r" alanının CS / SS / DS'den seçileceğini belirten bir "rseg" önekine sahip olmak olacaktır. / ES / FS / GS / ?? / ?? AX / BX / CX / DX / SI / DI / SP / BP yerine ve FS / GS için önekler ve LFS ve LGS için talimatlara (LDS ve LES gibi) sahip olmak. 8086 için mikro mimarinin nasıl tasarlandığını bilmiyorum, ama bunun gibi bir şeyin işe yarayabileceğini düşünürdüm.
SuperCat

@supercat: yazdığım gibi, "kayıtlar ayrıca ... dışında belleğe eksik bağlantıyı da sağlar." Hatırladığım kadarıyla Fs ve gs 386'ya kadar gelmedi.
Olof Forshell

1
@OlofForshell: Yapmadılar, bu da 80286 mimarisini 8086 mimarisinden çok daha kötü hale getirdi. Demek istediğim, birkaç segment kaydı (hatta bir tane daha) eklemek 8086 mimarisini çok daha kullanışlı hale getirebilirdi ve eğer segment kayıtlarına çok benzer şekilde erişilebilseydi komut seti daha temiz ve daha kullanışlı olabilirdi. diğerleri.
supercat
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.