32 bit bir sistem 2 ^ 33 bir sayıyı yönetemediğinden (bariz 32 bit sınırı nedeniyle), 80 bit kayan nokta sayısını nasıl yönetebilirim ?
"80 bit" gerektirir ...
32 bit bir sistem 2 ^ 33 bir sayıyı yönetemediğinden (bariz 32 bit sınırı nedeniyle), 80 bit kayan nokta sayısını nasıl yönetebilirim ?
"80 bit" gerektirir ...
Yanıtlar:
32 bit CPU'nun anlamlarından biri, kayıtlarının 32 bit genişliğidir. Bu 64 bit sayıları ile başa çıkamayacağı anlamına gelmez, sadece önce alt 32 bit yarım, daha sonra üst 32 bit yarım saniye ile uğraşması gerekir. (Bu yüzden CPU'ların taşıma bayrağı vardır .) CPU, değerleri sadece daha geniş bir 64 bit kayıt defterine yükleyebilse de daha yavaştır, ancak yine de mümkündür.
Bu nedenle, bir sistemin "bit" değeri, bir programın ele alabileceği sayıların boyutunu sınırlamak zorunda değildir, çünkü CPU kayıtlarına uymayacak işlemleri her zaman birden çok işleme ayırabilirsiniz. Bu nedenle işlemleri yavaşlatır, daha fazla bellek tüketir (belleği "not defteri" olarak kullanmanız gerekiyorsa) ve programlaması daha zordur, ancak işlemler yine de mümkündür.
Bununla birlikte, CPU'nun kayan nokta kısmı kendi kayıtlarına sahip olduğundan ve 80 bit genişliğinde olduğundan, bunların hiçbiri, örneğin Intel 32 bit işlemciler ve kayan nokta ile önemli değildir. (X86 tarihinin başlarında, kayan nokta kapasitesi ayrı bir çipti, 80486DX ile başlayan CPU'ya entegre edildi.)
@ Breakthrough'un cevabı bana bunu eklemem için ilham verdi.
Kayan nokta değerleri, FPU kayıtlarında saklandıkları sürece, ikili tamsayı değerlerinden çok farklı çalışır.
Kayan nokta değerinin 80 biti bir mantis ve üs arasında bölünür (kayan nokta sayılarında her zaman 2 olan "taban" da vardır). Mantis önemli basamakları içerir ve üs bu anlamlı basamakların ne kadar büyük olduğunu belirler. Başka bir kayıtta "taşma" olmaz, eğer numaranız mantis içine sığmayacak kadar büyük olursa, üssünüz artar ve hassasiyeti kaybedersiniz - yani bir tamsayıya dönüştürdüğünüzde, sağdaki ondalık basamakları kaybedersiniz - bu yüzden kayan nokta denir.
Üsünüz çok büyükse, kayan nokta taşması vardır, ancak üs ve mantis birbirine bağlı olduğundan başka bir kayda kolayca genişletemezsiniz.
Bazıları hakkında yanlış ve yanlış olabilirdim, ama bunun özü olduğuna inanıyorum. (Bu Wikipedia makalesi , yukarıdakileri biraz daha özlü bir şekilde göstermektedir.)
CPU'nun tüm "kayan nokta" kısmı kendi dünyasında olduğu için tamamen farklı çalışıyor - ona erişmek için özel CPU talimatları kullanıyorsunuz. Ayrıca, sorunun noktasına doğru, ayrı olduğu için, FPU'nun biti yerel CPU'nun biti ile sıkı bir şekilde birleşmez.
-fomit-frame-pointer
bu kaydı geri almak için kullanabilirsiniz .
32 bit, 64 bit ve 128 bit , işlemcinin "temel veri türü" olarak düşünülebilecek kelime uzunluğunu ifade eder. Genellikle, bu, sistemin RAM'ine / RAM'inden aktarılan bitlerin sayısı ve işaretçilerin genişliğidir (hiçbir şey tek bir işaretçinin erişebileceğinden daha fazla RAM'e erişmek için yazılım kullanmanıza engel olmamasına rağmen).
Sabit bir saat hızı (ve mimarideki diğer her şeyin sabit olduğu) varsayarsak ve bellek okuma / yazma işlemlerinin aynı hız olduğunu varsayarsak (burada 1 saat döngüsünü varsayarız, ancak bu gerçek hayatta durumdan çok uzaktır) 64 bitlik bir makinede tek bir saat döngüsünde iki adet 64 bitlik sayı ekleyin (sayıları RAM'den alırsanız üç adet):
ADDA [NUM1], [NUM2]
STAA [RESULT]
Biz de yapabiliriz 32 bit makinede aynı hesaplama 32 bit makinede ... Ancak, biz daha düşük 32-bit ilk eklenmelidir yana, taşma telafi, yazılımda bunu Gereksiz, ardından eklemek üst 64 bit:
ADDA [NUM1_LOWER], [NUM2_LOWER]
STAA [RESULT_LOWER]
CLRA ; I'm assuming the condition flags are not modified by this.
BRNO CMPS ; Branch to CMPS if there was no overflow.
ADDA #1 ; If there was overflow, compensate the value of A.
CMPS ADDA [NUM1_UPPER], [NUM2_UPPER]
STAA [RESULT_UPPER]
Yapılmış montaj sözdizimden geçerek, daha yüksek hassasiyetli işlemlerin daha düşük bir kelime uzunluğunda bir makinede nasıl katlanarak daha uzun sürebileceğini kolayca görebilirsiniz. Bu, 64 bit ve 128 bit işlemcilerin gerçek anahtarıdır: tek bir işlemde çok sayıda biti işlememize izin verir. Bazı makineler, taşıma ile başka miktarlar eklemek için talimatlar içerir (örn ADC
. X86'da), ancak yukarıdaki örnekte rastgele hassasiyet değerleri göz önünde bulundurulmaktadır.
Şimdi, bunu soruya genişletmek için, elimizdeki kayıtlardan daha büyük sayıları nasıl ekleyebileceğimizi görmek basit - sorunu sadece kayıtların boyutunu parçalara ayırıyoruz ve oradan çalışıyoruz. @MatteoItalia tarafından belirtildiği gibi , x87 FPU yığını, 80 bit miktarlar için yerel desteğe sahip olsa da , bu desteğe sahip olmayan sistemlerde (veya kayan nokta birimi eksik işlemcilerde!), Eşdeğer hesaplamalar / işlemler yazılımda gerçekleştirilmelidir .
Bu nedenle, 80 bitlik bir sayı için, her 32 bitlik segmenti ekledikten sonra, 81-bit bitine taşma olup olmadığı da kontrol edilir ve isteğe bağlı olarak yüksek dereceli bitler sıfırlanır. Bu kontroller / sıfırlar, kaynak ve hedef işlenen boyutlarının belirtildiği belirli x86 ve x86-64 talimatları için otomatik olarak gerçekleştirilir (ancak bunlar yalnızca 1 bayt genişlikten başlayarak 2'lik güçlerde belirtilir).
Tabii ki, kayan nokta sayıları ile, mantis ve önemli rakamlar ofset formunda bir araya getirildiğinden, ikili toplama basitçe gerçekleştirilemez. Bir x86 işlemcideki ALU'da, bunu IEEE 32 bit ve 64 bit şamandıralar için gerçekleştirmek için bir donanım devresi vardır; Bununla birlikte , daha da bir kayan nokta ünitesi (FPU) yokluğunda, aynı hesaplamaları kullanımı yoluyla, örneğin bir yazılım (yapılabilir GNU Bilimsel Kütüphanesi yazılım algoritmaları geri düşme ile mimarileri derlenmiş bir FPU kullanır hiçbir kayan noktalı donanım yoksa [örneğin FPU'ları olmayan gömülü mikrodenetleyiciler için]).
Yeterli bellek verildiğinde , daha fazla hassasiyet gerektiğinden daha fazla bellek kullanarak rasgele (veya "sonsuz" - gerçekçi sınırlar dahil) sayılarda hesaplamalar da yapılabilir . Bunun bir uygulaması, GNU Çok Hassasiyetli kütüphanesinde mevcuttur ve tamsayı, rasyonel ve kayan nokta işlemlerinde sınırsız hassasiyet (RAM'iniz dolana kadar) sağlar.
Sistemin bellek mimarisi yalnızca bir kerede 32 bit hareket etmenize izin verebilir - ancak bu, daha büyük sayılar kullanmasını engellemez.
Çarpmayı düşünün. Çarpma tablolarınızı 10x10'a kadar biliyor olabilirsiniz, ancak muhtemelen bir kağıda 123x321 yapmakta sorun yaşamazsınız: sadece birçok küçük probleme böler, tek tek rakamları çoğaltır ve taşımaya özen gösterirsiniz.
İşlemciler de aynı şeyi yapabilir. "Eski günlerde" kayan nokta matematiği yapabilen 8 bit işlemcilere sahiptiniz. Ama slooooooow idi.
"32-bit" gerçekten işlemcileri kategorize etmenin bir yolu, taştan yapılmış bir karar değil. bir "32-bit" işlemci tipik olarak çalışmak için 32-bit genel amaçlı kayıtlara sahiptir.
Ancak, işlemcideki her şeyin 32 bit olarak yapılması için taş gereksinimi yoktur. Örneğin, "32 bit" bir bilgisayarın 28 bit adres veriyoluna sahip olması duyulmamıştı, çünkü donanımı yapmak daha ucuzdu. 64 bit bilgisayarlarda genellikle aynı nedenden ötürü yalnızca 40 bit veya 48 bit bellek veri yolu bulunur.
Kayan nokta aritmetiği, boyutların değiştiği başka bir yerdir. Birçok 32 bit işlemci 64 bit kayan nokta sayısını destekledi. Bunu, genel amaçlı kayıtlardan daha geniş olan özel kayıtlarda kayan nokta değerlerini depolayarak yaptılar. Bu büyük kayan nokta numaralarından birini özel kayıtlarda saklamak için, önce numarayı iki genel amaçlı kayıt arasında böler, sonra bunları özel kayıtlardaki bir kayan noktaya birleştirmek için bir talimat verir. Bu kayan nokta yazmaçlarında, değerler bir çift 32-bit yarıdan ziyade 64-bit float olarak işlenir.
Bahsettiğiniz 80-bit aritmetik bunun özel bir örneğidir. Kayan nokta sayıları ile çalıştıysanız, kayan nokta yuvarlama sorunlarından kaynaklanan kesinsizliği biliyorsunuzdur. Yuvarlama için bir çözüm daha fazla hassasiyete sahip olmaktır, ancak daha sonra daha büyük sayılar depolamanız ve geliştiricileri bellekte alışılmadık derecede büyük kayan nokta değerleri kullanmaya zorlamanız gerekir.
Intel çözümü, kayan nokta kayıtlarının hepsinin 80 bit olduğu, ancak değerleri bu kayıtlara / kayıtlardan taşıma talimatları öncelikle 64 bit sayılarla çalışır. Tamamen Intel'in x87 kayan nokta yığını içinde çalıştığınız sürece, tüm işlemleriniz 80 bit hassasiyetle yapılır. Kodunuzun bu değerlerden birini kayan nokta kayıtlarından çıkarması ve bir yerde saklaması gerekiyorsa, 64 bit olarak keser.
Hikayenin ahlakı: "32-bit" gibi kategoriler her şeyi derinleştirdiğinizde her zaman daha tehlikelidir!
"32-bit" CPU, veri kayıtlarının çoğunun 32-bit kayıt olduğu ve talimatların çoğunun bu 32-bit kayıtlardaki veriler üzerinde çalıştığı bir CPU'dur. 32 bit CPU'nun aynı anda 32 bitlik belleğe veri aktarması da mümkündür. Kayıtların çoğu 32-bit olmak, tüm kayıtların 32-bit olduğu anlamına gelmez. Kısa cevap, 32 bit CPU'nun 80 bit kayan nokta kayıtları ve ilgili talimatlar gibi diğer bit sayımlarını kullanan bazı özelliklere sahip olabilmesidir.
@Spudone'un @ ultrasawblade'in cevabı hakkındaki bir yorumda söylediği gibi, entegre kayan nokta işlemlerine sahip ilk x86 CPU , i486 Mikroişlemci Programcılarının Intel i486 (özellikle 80486DX değil 80486SX değil) idi. Referans Kılavuzu , sayısal kayıtlarında "Sekiz ayrı adreslenebilir 80 bit sayısal kayıt" içermektedir. İ486'nın 32 bit bellek veri yolu vardır, bu nedenle 80 bit değerinin aktarılması 3 bellek işlemi gerektirir.
486 neslinin öncüsü olan i386'nın entegre kayan nokta işlemi yoktu. Bunun yerine, 80387 harici kayan nokta "yardımcı işlemci" kullanma desteğine sahipti. Bu yardımcı işlemci , 80387 Programcı Referans Kılavuzu'nun Sayfa 2-1'inden görebileceğiniz gibi i486'ya entegre edilmiş neredeyse aynı işlevselliğe sahipti .
80-bit kayan nokta formatı, 8086 ve 8088 için matematik yardımcı işlemcisi olan 8087'den kaynaklanıyor gibi görünüyor. 8086 ve 8088, 16-bit CPU'lar (16-bit ve 8-bit bellek veriyolları ile) ve hala yardımcı işlemcideki 80 bit kayıtlardan yararlanarak 80 bit kayan nokta biçimini kullanmak.