Pertanyaan ini sudah ada jawabannya di sini:
Karena sistem 32bit tidak dapat mengelola angka 2 ^ 33 (karena batas 32-bit yang jelas), bagaimana cara mengelola angka titik mengambang 80-bit ?
Seharusnya membutuhkan "80-bit" ...
Pertanyaan ini sudah ada jawabannya di sini:
Karena sistem 32bit tidak dapat mengelola angka 2 ^ 33 (karena batas 32-bit yang jelas), bagaimana cara mengelola angka titik mengambang 80-bit ?
Seharusnya membutuhkan "80-bit" ...
Jawaban:
Salah satu arti dari CPU 32 bit adalah registernya memiliki lebar 32 bit. Ini tidak berarti itu tidak bisa berurusan dengan mengatakan, angka 64 bit, hanya saja harus berurusan dengan setengah bit 32 pertama, kemudian bagian atas 32 bit setengah detik. (Itu sebabnya CPU memiliki flag carry .) Lebih lambat daripada jika CPU hanya bisa memuat nilai-nilai dalam register 64 bit yang lebih luas, tetapi masih mungkin.
Dengan demikian, "bitness" dari suatu sistem tidak harus membatasi ukuran angka yang dapat ditangani oleh suatu program, karena Anda selalu dapat memecah operasi yang tidak akan masuk ke dalam register CPU menjadi beberapa operasi. Jadi itu membuat operasi lebih lambat, mengkonsumsi lebih banyak memori (jika Anda harus menggunakan memori sebagai "scratchpad"), dan lebih sulit untuk diprogram, tetapi operasi masih mungkin dilakukan.
Namun, tidak ada yang penting dengan, misalnya, prosesor Intel 32 bit dan floating point, karena bagian floating point dari CPU memiliki register sendiri dan lebar 80 bit. (Di awal sejarah x86, kemampuan floating point adalah chip yang terpisah, itu terintegrasi dalam CPU yang dimulai dengan 80486DX.)
@ Jawaban terobosan mengilhami saya untuk menambahkan ini.
Nilai floating point, sejauh disimpan dalam register FPU, bekerja sangat berbeda dari nilai integer biner.
80 bit nilai floating point dibagi antara mantissa dan eksponen (ada juga "basis" dalam angka floating point yang selalu 2). Mantera mengandung digit signifikan, dan eksponen menentukan seberapa besar digit signifikan tersebut. Jadi tidak ada "overflow" ke register lain, jika nomor Anda menjadi terlalu besar untuk dimasukkan dalam mantissa, eksponen Anda meningkat dan Anda kehilangan presisi - yaitu ketika Anda mengonversinya menjadi bilangan bulat, Anda akan kehilangan tempat desimal dari kanan - inilah mengapa ini disebut floating point.
Jika eksponen Anda terlalu besar, maka Anda memiliki luapan floating-point, tetapi Anda tidak dapat dengan mudah memperluasnya ke register lain karena eksponen dan mantissa terikat bersama.
Saya bisa saja tidak akurat dan salah tentang hal itu, tetapi saya yakin itulah intinya. ( Artikel Wikipedia ini menggambarkan hal di atas sedikit lebih ringkas.)
Tidak apa-apa kalau ini bekerja dengan sangat berbeda karena seluruh bagian "floating-point" dari CPU itu seperti di dunianya sendiri - Anda menggunakan instruksi CPU khusus untuk mengaksesnya dan semacamnya. Juga, menuju titik pertanyaan, karena terpisah, bitness dari FPU tidak erat dengan bitness dari CPU asli.
-fomit-frame-pointer
untuk mendapatkan register itu kembali.
32-bit, 64-bit, dan 128-bit semuanya merujuk pada panjang kata dari prosesor, yang dapat dianggap sebagai "tipe data mendasar". Seringkali, ini adalah jumlah bit yang ditransfer ke / dari RAM sistem, dan lebar pointer (meskipun tidak ada yang menghentikan Anda dari menggunakan perangkat lunak untuk mengakses lebih banyak RAM daripada apa yang dapat diakses oleh satu pointer).
Dengan asumsi kecepatan clock konstan (serta semua yang lain dalam arsitektur menjadi konstan), dan dengan asumsi memori baca / tulis adalah kecepatan yang sama (kami menganggap 1 clock cycle di sini, tetapi ini jauh dari kasus dalam kehidupan nyata), Anda dapat tambahkan dua angka 64-bit dalam satu siklus clock tunggal pada mesin 64-bit (tiga jika Anda menghitung mengambil angka dari RAM):
ADDA [NUM1], [NUM2]
STAA [RESULT]
Kita juga dapat melakukan perhitungan yang sama pada mesin 32-bit ... Namun, pada mesin 32-bit, kita perlu melakukan ini dalam perangkat lunak, karena 32-bit yang lebih rendah harus ditambahkan terlebih dahulu, ganti rugi dengan overflow, kemudian tambahkan 64-bit atas:
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]
Melihat sintaks perakitan buatan saya, Anda dapat dengan mudah melihat bagaimana operasi dengan presisi lebih tinggi dapat memakan waktu lebih lama secara eksponensial pada mesin dengan panjang kata yang lebih rendah. Ini adalah kunci nyata untuk prosesor 64-bit dan 128-bit: mereka memungkinkan kami untuk menangani jumlah bit yang lebih besar dalam satu operasi. Beberapa mesin menyertakan instruksi untuk menambahkan jumlah lain dengan carry (misalnya ADC
pada x86), tetapi contoh di atas memiliki nilai presisi yang berubah-ubah.
Sekarang, untuk memperluas pertanyaan ini, mudah untuk melihat bagaimana kita dapat menambahkan angka yang lebih besar dari register yang tersedia - kita hanya memecah masalah menjadi potongan-potongan ukuran register, dan bekerja dari sana. Meskipun seperti yang disebutkan oleh @MatteoItalia , stack FPU x87 memiliki dukungan asli untuk jumlah 80-bit, dalam sistem yang tidak memiliki dukungan ini (atau prosesor yang tidak sepenuhnya memiliki unit floating point!), Perhitungan / operasi yang setara harus dilakukan dalam perangkat lunak .
Jadi untuk angka 80-bit, setelah menambahkan setiap segmen 32-bit, orang juga akan memeriksa melimpah ke bit 81-st, dan secara opsional nol urutan bit yang lebih tinggi. Pemeriksaan / nol ini dilakukan secara otomatis untuk instruksi x86 dan x86-64 tertentu, di mana ukuran operan sumber dan tujuan ditentukan (meskipun ini hanya ditentukan dalam kekuatan 2 mulai dari lebar 1 byte).
Tentu saja, dengan angka floating point, kita tidak bisa begitu saja melakukan penambahan biner karena mantissa dan digit signifikan dikemas bersama dalam bentuk offset. Dalam ALU pada prosesor x86, ada sirkuit perangkat keras untuk melakukan ini untuk IEEE 32-bit dan 64-bit float; Namun , bahkan tanpa adanya floating-point unit (FPU), perhitungan yang sama dapat dilakukan dalam perangkat lunak (misalnya melalui penggunaan Perpustakaan Ilmiah GNU , yang menggunakan FPU ketika dikompilasi pada arsitektur dengan, kembali ke algoritma perangkat lunak jika tidak ada perangkat keras floating-point yang tersedia [misalnya untuk mikrokontroler tertanam yang tidak memiliki FPU]).
Mengingat memori yang cukup, seseorang juga dapat melakukan perhitungan pada angka presisi yang arbitrer (atau "tak terbatas" - dalam batas realistis), menggunakan lebih banyak memori karena dibutuhkan lebih banyak presisi. Salah satu implementasi dari hal ini ada di pustaka GNU Multiple Precision , memungkinkan presisi tak terbatas (hingga RAM Anda penuh, tentu saja) pada operasi integer, rasional, dan floating point.
Arsitektur memori sistem hanya memungkinkan Anda untuk memindahkan 32 bit sekaligus - tetapi itu tidak menghentikannya menggunakan angka yang lebih besar.
Pikirkan tentang multiplikasi. Anda mungkin tahu tabel perkalian Anda hingga 10x10, namun Anda mungkin tidak memiliki masalah melakukan 123x321 pada selembar kertas: Anda hanya memecahnya menjadi banyak masalah kecil, mengalikan digit individu, dan mengurus carry dll.
Prosesor dapat melakukan hal yang sama. Dalam "masa lalu" Anda memiliki prosesor 8 bit yang bisa melakukan matematika titik mengambang. Tapi mereka slooooooow.
"32-bit" benar-benar cara untuk mengkategorikan prosesor, bukan putusan set-in-stone. prosesor "32-bit" biasanya memiliki register tujuan umum 32 bit untuk bekerja dengannya.
Namun, tidak ada persyaratan yang pasti bahwa semua yang ada di prosesor harus dilakukan dalam 32-bit. Sebagai contoh, itu tidak pernah terdengar untuk komputer "32-bit" untuk memiliki bus alamat 28-bit, karena lebih murah untuk membuat perangkat keras. Komputer 64-bit sering hanya memiliki bus memori 40-bit atau 48-bit untuk alasan yang sama.
Aritmatika titik apung adalah tempat lain di mana ukuran bervariasi. Banyak prosesor 32-bit mendukung angka floating point 64-bit. Mereka melakukannya dengan menyimpan nilai floating point di register khusus yang lebih luas dari register tujuan umum. Untuk menyimpan salah satu dari angka-angka floating point besar ini dalam register khusus, seseorang pertama-tama akan membagi angka di dua register tujuan umum, kemudian mengeluarkan instruksi untuk menggabungkannya ke float di register khusus. Sekali dalam register floating point itu, nilai-nilai akan dimanipulasi sebagai float 64-bit, bukan sebagai sepasang bagian 32-bit.
Aritmatika 80-bit yang Anda sebutkan adalah kasus khusus ini. Jika Anda telah bekerja dengan angka floating point, Anda terbiasa dengan ketidaktepatan yang timbul dari masalah pembulatan floating point. Salah satu solusi untuk pembulatan adalah memiliki lebih banyak bit presisi, tetapi kemudian Anda harus menyimpan angka yang lebih besar, dan memaksa pengembang untuk menggunakan nilai floating point yang luar biasa besar dalam memori.
Solusi Intel adalah bahwa register titik mengambang semuanya 80 bit, tetapi instruksi untuk memindahkan nilai ke / dari register-register tersebut secara primer bekerja dengan angka 64-bit. Selama Anda beroperasi sepenuhnya dalam tumpukan floating point Intel x87, semua operasi Anda dilakukan dengan presisi 80 bit. Jika kode Anda perlu menarik salah satu dari nilai-nilai itu dari register floating point dan menyimpannya di suatu tempat, ia memotongnya menjadi 64-bit.
Moral dari cerita: kategorisasi seperti "32-bit" selalu lebih berbahaya ketika Anda masuk lebih dalam ke hal-hal!
CPU "32-bit" adalah dimana sebagian besar register data adalah register 32-bit, dan sebagian besar instruksi beroperasi pada data dalam register 32-bit tersebut. CPU 32-bit juga cenderung untuk mentransfer data ke dan dari memori 32-bit pada suatu waktu. Sebagian besar register menjadi 32-bit tidak berarti semua register adalah 32-bit. Jawaban singkatnya adalah bahwa CPU 32-bit dapat memiliki beberapa fitur yang menggunakan bitcount lainnya, seperti register floating point 80-bit dan instruksi yang sesuai.
Seperti yang dikatakan @spudone dalam komentar pada jawaban @ ultrasawblade, CPU x86 pertama yang mengintegrasikan operasi floating-point adalah Intel i486 (khususnya 80486DX tetapi bukan 80486SX), yang, menurut Halaman 15-1 dari Programmer Mikroprosesor i486 Referensi Manual , termasuk dalam register numeriknya "Delapan register numerik 80-bit yang dapat dialamatkan secara individual". I486 memiliki bus memori 32-bit, jadi mentransfer nilai 80-bit akan membutuhkan 3 operasi memori.
Pendahulu generasi 486, i386, tidak memiliki operasi floating-point terintegrasi. Sebagai gantinya, ia memiliki dukungan untuk menggunakan floating point "coprocessor" eksternal, 80387. Coprocessor ini memiliki fungsi yang hampir sama dengan yang diintegrasikan ke i486, seperti yang Anda lihat dari Halaman 2-1 dari Manual Referensi Programmer 80387 .
Format floating point 80-bit tampaknya berasal dari 8087, coprocessor matematika untuk 8086 dan 8088. 8086 dan 8088 adalah CPU 16-bit (dengan bus memori 16-bit dan 8-bit), dan masih dapat untuk menggunakan format floating point 80-bit, dengan memanfaatkan register 80-bit di coprocessor.