Bagaimana floating point 80-bit dapat digunakan oleh sistem 32-bit? [duplikat]

13

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

markzzz
sumber
8
Cara yang sama ia melakukan angka floating point 64-bit. Ia menggunakan 3 atau (2) register 32-bit. Karena angka floating point 80-bit bahkan bukan ukuran standar, itu sebenarnya akan menjadi angka 96-bit dengan hanya 80-bit yang digunakan.
Ramhound
5
ketika Anda khawatir tentang platform bittedness, Anda khawatir tentang kerja bagian dalam CPU seperti yang orang lain katakan, dan cara instruksi dijalankan secara asli pada sistem. Angka IEEE754 biasanya langsung dapat diproses di unit eksekusi FPU CPU Anda, sedangkan angka 128bit akan memerlukan penggunaan beberapa instruksi yang diprogram sedemikian rupa sehingga mereka dapat mengagregasi makna nilai yang dievaluasi oleh aplikasi. yang meninggalkan pemrosesan nomor hingga aplikasi.
Frank Thomas
2
@ Ƭᴇcʜιᴇ007 Tidak cukup menipu yang satu itu. Yang satu itu lebih tentang perbedaan antara angka dan representasi teks / ASCII-nya, meskipun beberapa jawaban itu mungkin juga membahas hal ini.
Bob
3
Di hampir semua mesin modern, floating point ditangani oleh prosesor yang terpisah (meskipun biasanya pada chip yang sama dengan prosesor utama). Semua prosesor seperti itu tahu cara menangani 80-bit (meskipun beberapa melakukannya jauh lebih cepat daripada yang lain). ( Dan "lebar" dari prosesor adalah sesuatu yang fiksi. )
Daniel R Hicks
6
@Ramhound: Tidak, 80 bit adalah kekhasan 8087, dan menggunakan 1 register FP. Ini jelas bukan angka 96 bit.
MSalters

Jawaban:

35

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.

LawrenceC
sumber
4
Semua yang Anda tambahkan dari inspirasi saya benar, jadi jangan khawatir di sana :) Hanya satu poin yang harus saya sebutkan, meskipun Anda dapat menggunakan instruksi CPU asli di mana unit floating-point ada, Anda juga dapat melakukan operasi floating point dalam perangkat lunak (dengan bitwise yang setara atau operasi bilangan bulat matematika). Untuk memperluas ke titik itu, mengingat memori yang cukup, Anda juga dapat memiliki angka presisi sewenang - wenang (sebagai lawan dari 64-bit tetap kami, atau 80-bit dalam hal ini) menggunakan algoritme / pustaka perangkat lunak (yang biasanya digunakan adalah GNU Multiple Precision) perpustakaan ).
Terobosan
1
Nitpick: FPU terintegrasi Intel pertama ada di 80486DX, bukan 80386.
spudone
2
@markzzz: Tidak ada yang gila jika diperlukan. Menggunakan pelampung 16bit untuk mensimulasikan bom atom untuk mengevaluasi cadangan nuklir Anda gila karena itu tidak cukup tepat bagi Anda untuk percaya diri dalam hasilnya. Dalam hal ini diperlukan 32 bit (dan ya, di masa lalu perhitungan ini dilakukan pada PDP 16 bit). Demikian pula menggunakan folat 32bit untuk mensimulasikan iklim tidak cukup tepat karena sifat perhitungan yang kacau.
Slebetman
2
FWIW, cara umum untuk menerapkan operasi floating point pada mesin tanpa unit FP dengan ukuran yang Anda inginkan adalah melakukannya dalam perangkat lunak menggunakan instruksi integer. Karena, pada akhirnya, eksponen dan mantissa dari angka floating point hanyalah bilangan bulat. Begitulah cara kami menafsirkannya yang memberi mereka makna khusus.
slebetman
2
@ PTw pada x86 Anda sebenarnya memiliki 7 GPR yang dapat digunakan untuk data, termasuk EBP. Hanya saja, sebagian besar implementasi bahasa ABI menyimpan register ini untuk penunjuk bingkai tumpukan. Tetapi misalnya dengan GCC yang dapat Anda gunakan -fomit-frame-pointeruntuk mendapatkan register itu kembali.
Ruslan
13

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

Penerobosan
sumber
2
Anda gagal menyebutkan detail yang paling penting: FPU x87 pada platform x86 memiliki register floating point selebar 80-bit, sehingga perhitungan aslinya sebenarnya dilakukan pada float 80 bit, tidak perlu meniru apa pun dalam perangkat lunak.
Matteo Italia
@MatteoItalia Saya melihat itu sekarang, terima kasih. Saya pikir pertanyaan awal adalah meminta gambaran umum yang lebih umum tentang bagaimana seseorang dapat melakukan operasi pada angka yang lebih besar dari ukuran kata prosesor, dan bukan implementasi spesifik dari float 80-bit yang diperluas di x86 (juga mengapa contoh saya adalah 90 bit, bukan 80 ...). Saya telah memperbarui jawabannya sekarang untuk mencerminkan hal ini dengan lebih baik, terima kasih atas jawabannya.
Terobosan
5

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.

Floris
sumber
1
Mereka lambat hanya setelah titik tertentu. Anda dapat menulis operasi titik apung "cepat" jika Anda membatasi diri pada spesifikasi tertentu.
Ramhound
3

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

Cort Ammon
sumber
Tetapi jika saya menggunakan nilai floating point 32bit ke dalam sistem 16bit (atau nilai floating point 64 bit ke dalam sistem 32 bit) hanya memerlukan lebih banyak memori (karena harus dua kali mendaftar)? Atau memproses informasi akan menambah overhead, sehingga akan memakan waktu lebih banyak?
markzzz
@markzzz: Bekerja dengan banyak register hampir selalu membutuhkan lebih banyak waktu
Mooing Duck
Memuat nilai titik apung 32bit ke register tujuan khusus akan membutuhkan lebih banyak waktu. Namun, begitu mereka disimpan sebagai pelampung 32-bit di register floating point tujuan khusus, perangkat keras akan beroperasi pada nilai-nilai floating point tersebut dengan kecepatan penuh. Ingat, "16-bit" hanya mengacu pada ukuran register tujuan UMUM. Register floating point berukuran khusus untuk tugas mereka, dan mungkin lebih lebar (lebar 32 bit dalam kasus Anda)
Cort Ammon
2

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.

ShadSterling
sumber