Bagaimana bahasa memengaruhi desain CPU? [Tutup]

44

Kita sering diberi tahu bahwa perangkat keras itu tidak peduli bahasa apa yang ditulis oleh sebuah program karena hanya melihat kode biner yang dikompilasi, namun ini bukan kebenaran sebenarnya. Misalnya, perhatikan Z80 yang sederhana; ekstensi ke set instruksi 8080 mencakup instruksi seperti CPIR yang berguna untuk memindai string gaya-C (dihentikan-NULL), misalnya untuk melakukan strlen(). Para desainer harus mengidentifikasi bahwa menjalankan program C (sebagai lawan dari Pascal, di mana panjang string ada di header) adalah sesuatu yang mungkin digunakan untuk desain mereka. Contoh klasik lainnya adalah Mesin Lisp .

Apa contoh lain yang ada? Misalnya instruksi, jumlah dan jenis register , mode pengalamatan, yang membuat prosesor tertentu menyukai konvensi bahasa tertentu? Saya khususnya tertarik pada revisi keluarga yang sama.

Gayus
sumber
3
Jangan lupa bahwa Z-80 juga memiliki instruksi LDIR, sangat berguna saat menyalin string ketika Anda tahu panjangnya (seperti dalam Pascal, di mana panjangnya disimpan di header).
TMN
27
1. Z-80 dirancang pada tahun 1975, ketika Unix dan C adalah sistem operasi dan bahasa yang tidak jelas pada beberapa komputer, 3 tahun sebelum K&R edisi pertama. 2. Tidak ada apa-apa tentang Pascal yang mengamanatkan panjang string menjadi "dalam header." 3. String dalam CP / M, OS komputer mikro utama pada saat itu, diakhiri dengan karakter '$', bukan '\ 0'. CPIR dapat mencari karakter apa pun. 4. CPIR cocok dengan CPDR (cari mundur), serta instruksi -IR dan -DR lainnya. Kesimpulan: CPIR tidak ada hubungannya dengan bahasa pemrograman C. Itu hanya instruksi pencarian byte.
Libib
4
Yang terbesar (dan salah satu yang paling menjengkelkan bagi perancang perangkat keras) dari hal-hal yang dipaksakan oleh C adalah pengalamatan byte. CPU akan lebih sederhana dan lebih cepat tanpa kekejian ini.
SK-logic
1
@ SK-logic: Meskipun standar POSIX membutuhkan pengalamatan byte, standar C tidak. Setiap implementasi di mana sizeof(int)sama dengan 1 harus mengharuskan jenis charitu ditandatangani (karena intharus dapat menampung semua nilai jenis char). Saya telah menulis kode untuk mesin di mana chardan intkeduanya bilangan bulat bertanda 16-bit; kesulitan terbesar adalah bahwa seseorang tidak dapat menggunakan serikat untuk konversi tipe, dan penyimpanan efisien dari sejumlah besar byte memerlukan pengemasan dan pembongkaran manual. Masalah-masalah itu kecil dibandingkan dengan kemungkinan dalam C yang sizeof (int) == sizeof (panjang), karena ...
supercat
2
... itu berarti tidak ada tipe standar yang dijamin memiliki perbedaan antara dua unsigned intnilai. C99 memperbaiki situasi itu, tetapi sebelum C99 tidak ada cara satu langkah yang dijamin aman untuk membandingkan nilai yang berpotensi negatif dengan nilai tipe unsigned int(orang harus menguji apakah jumlahnya negatif sebelum melakukan perbandingan).
supercat

Jawaban:

20

Jawaban yang ada fokus pada perubahan ISA . Ada perubahan perangkat keras lain juga. Misalnya, C ++ biasanya menggunakan vtables untuk panggilan virtual. Dimulai dengan Pentium M , Intel memiliki komponen "predictor cabang tidak langsung" yang mempercepat panggilan fungsi virtual.

MSalters
sumber
6
Dan arsitektur Berkeley RISC termasuk konsep "register file", jadi alih-alih membuat fungsi "spill" register ke stack, blok 8 register diberikan ke masing-masing fungsi. Ini mempercepat kode berorientasi objek, karena cenderung terdiri dari banyak pemanggilan metode untuk metode pendek.
TMN
1
Ini bukan contoh yang valid. Desain "Table of function pointer" juga digunakan dalam banyak skenario penautan dinamis, misalnya, melalui impor dan ekspor DLL pada Windows, dan juga digunakan dalam program C. Meskipun saya kira Anda bisa berpendapat bahwa itu memang menunjukkan prosesor yang dioptimalkan untuk penggunaan tertentu, itu tidak khusus bahasa.
DeadMG
@DeadMG: Kasus-kasus lain diuntungkan, itu benar. Tetapi sampai C ++ menjadi populer, desain CPU tidak terpengaruh . Dan itu adalah pertanyaan yang diajukan. Demikian pula, TMN memang memiliki poin tentang mendaftar file. Majelis tidak memiliki konsep fungsi yang jelas. Fungsi, seperti yang biasa kita pahami hari ini, tanggal kembali ke Algol 60, dan karena itu kita dapat mengatakan bahwa Algol 60 mempengaruhi desain file register CPU.
MSalters
14

Set instruksi Intel 8086 mencakup variasi "ret" yang menambahkan nilai ke penunjuk tumpukan setelah membuka alamat pengirim. Ini berguna untuk banyak implementasi Pascal di mana pemanggil suatu fungsi akan mendorong argumen ke stack sebelum melakukan pemanggilan fungsi, dan mematikannya setelahnya. Jika sebuah rutin menerima misalnya parameter bernilai empat byte, itu bisa diakhiri dengan "RET 0004" untuk membersihkan tumpukan. Jika tidak ada instruksi seperti itu, konvensi pemanggilan seperti itu mungkin akan mengharuskan kode untuk membuka kembali alamat ke register, memperbarui penunjuk tumpukan, dan kemudian melompat ke register itu.

Menariknya, sebagian besar kode (termasuk rutinitas OS) pada Macintosh asli menggunakan konvensi pemanggilan Pascal meskipun tidak ada instruksi fasilitasi di 68000. Menggunakan konvensi pemanggilan ini menyimpan 2-4 byte kode di situs panggilan biasa, tetapi membutuhkan tambahan 4-6 byte kode di situs kembali setiap fungsi yang mengambil parameter.

supercat
sumber
Ada juga ENTERmitra untuk ini RET n...
herby
1
@herby: Saya tidak berpikir ENTERada di 8086 yang asli; itu datang dengan prosesor kemudian. Itu memang memunculkan poin yang menarik, meskipun: mode pengalamatan berbasis BP jelas dirancang di sekitar penggunaan parameter bertumpuk dan penduduk lokal diakses melalui frame pointer. Saya menemukan konvensi ini menarik dalam beberapa cara, terutama mengingat (1) kode bahasa rakitan murni lebih cenderung menggunakan nilai dalam register daripada tumpukan, tetapi (2) keuntungan dari [BP + nn] menangani lebih dari [SP + nn] menangani lebih penting untuk program bahasa assembly yang mengakses berbagai hal di stack daripada ...
supercat
... untuk kode perakitan tulisan tangan. Kompiler pada umumnya akan tahu, untuk setiap instruksi yang dihasilkan, bagaimana SP dan BP membandingkan; jika SP adalah BP-8, misalnya, itu tidak benar-benar lebih mudah bagi kompiler untuk mengatasi [BP + 12] daripada [SP + 20]. Jika pada kompilasi ulang kompiler harus menambahkan PUSH / POP lain di sekitar blok kode, ia dapat menyesuaikan offset berbasis SP dengan tepat. Di sisi lain, dalam rakitan tulisan tangan, menambahkan PUSH / POP akan lebih mungkin membutuhkan mengubah kode di antara mereka. Jadi frame pointer terutama bermanfaat untuk kode tingkat tinggi / asm.
supercat
Mungkin kemungkinan untuk menggunakan kembali kode tanpa kompilasi ulang juga merupakan beberapa poin kegunaan marjinal untuk mengatasi BP. Dan Tuhan tahu jika instruksi pengalamatan BP tidak lebih cepat di sirkuit daripada yang dialamatkan SP, karena pengalamatan BP adalah semacam standar ...
herby
3
@herby: Sebenarnya, saya menduga sebagian besar alasan kompiler umumnya menggunakan frame pointer memiliki banyak hubungannya dengan debugging. Untuk men-debug sebuah program yang tidak menggunakan konvensi semacam itu akan mengharuskan compiler menghasilkan - dan penggunaan debugger - file yang mencantumkan offset SP-BP untuk setiap instruksi. Metadata terperinci semacam itu sudah umum saat ini (dan merupakan bagian penting dari apa yang membuat bahasa yang dikumpulkan sampah praktis) tetapi jumlah RAM yang dibutuhkannya tidak dapat diterima 30 tahun yang lalu.
supercat
10

Salah satu contoh adalah MIPS, yang memiliki keduanya adddan adduuntuk menjebak dan mengabaikan overflow masing-masing. (Juga subdan subu.) Dibutuhkan jenis instruksi pertama untuk bahasa seperti Ada (saya pikir - saya belum pernah benar-benar menggunakan Ada) yang menangani overflow secara eksplisit dan tipe kedua untuk bahasa seperti C yang mengabaikan overflow.

Jika saya ingat dengan benar, CPU sebenarnya memiliki beberapa sirkuit tambahan di ALU untuk melacak kelebihan. Jika satu-satunya bahasa yang dipedulikan orang adalah C, tidak perlu ini.

Tikhon Jelvis
sumber
Tidak yakin jika terkait, tetapi instruksi itu mungkin juga berguna dalam situasi lain, seperti alokasi memori yang aman, yaitu jika Anda mengalokasikan nmemb*size+offsetbyte dan perlu memastikan bahwa Anda tidak mendapatkan overflow.
NikiC
@NikC: Saya berpikir bahwa addudan subuinstruksi (yang tidak memeriksa luapan) adalah yang ditambahkan untuk membuat C bahagia. Tentu saja, saya tidak benar-benar tahu - kami hanya membahasnya secara samar-samar dalam perkuliahan dan saya jelas bukan ahli dalam arsitektur: P.
Tikhon Jelvis
Oh ya, saya berpikir sebaliknya, maaf: /
NikiC
8

Seri Burroughs 5000 dirancang untuk secara efisien mendukung ALGOL, dan Intel iAPX-432 dirancang untuk secara efisien mengeksekusi Ada. Inmos Transputer memiliki bahasa sendiri, Occam. Saya pikir prosesor "Propeller" Parallax dirancang untuk diprogram menggunakan varian BASIC-nya sendiri.

Ini bukan bahasa, tetapi set instruksi VAX-11 memiliki satu instruksi untuk memuat konteks proses, yang dirancang setelah permintaan dari tim desain VMS. Saya tidak ingat detailnya, tetapi ISTR butuh begitu banyak instruksi untuk diimplementasikan sehingga menempatkan batas atas yang serius pada jumlah proses yang dapat mereka jadwalkan.

TMN
sumber
Ada apa dengan desain ini yang membuatnya sangat cocok? Misalnya, fitur apa dari iAPX yang manfaat khususnya dari Ada?
Gayus
ISTR bahwa target Ada dari iAPX-432 lebih berusaha untuk menyelamatkan desain yang gagal dengan melampirkannya pada sesuatu dengan harapan yang besar daripada yang lainnya.
AProgrammer
@AProgrammer: Saya cukup yakin iAPX-432 dirancang dari awal untuk menggunakan Ada. Saya bahkan ingat beberapa rumor bahwa Intel tidak akan menerbitkan set instruksi, untuk mencegah pemrograman bahasa assembly dan memaksa orang untuk menggunakan Ada untuk semuanya.
TMN
1
@TMN, proyek Intel 432 dimulai pada 1975 dan diperkenalkan pada 1981 (Wikipedia). Ironman (persyaratan akhir untuk Ada), diterbitkan pada Januari 1977, dan hijau dipilih pada Mei 1979, dimodifikasi dan hasil akhir diterbitkan sebagai standar militer pada Juli 1980. Ada masalah garis waktu dalam menyatakan bahwa iAPX-432 dirancang dari mulai menggunakan Ada. (Ini adalah prosesor "tutup semantic gap" yang terlambat dan tipikal dengan kelemahan yang biasa terjadi pada saat alternatif mulai dicari; pemasaran karena prosesor Ada adalah tentatif untuk menyelamatkan desain yang gagal - ISTR yang tidak lain kecuali Intel yang menggunakannya )
Pemrogram
1
@AProgrammer: Hmmm, sepertinya Anda benar. Saya berlari melintasi makalah ini dari arsitek utama 432 dan dalam ringkasan ia mengatakan, "Arsitektur dan bahasa yang serasi ini tidak terjadi karena 432 dirancang untuk mengeksekusi Ada — bukan itu." Saya harus menggali buku lama 432 saya dan melihat apa katanya.
TMN
8

Satu hal yang tampaknya tidak disebutkan oleh siapa pun sejauh ini adalah bahwa kemajuan dalam optimisasi kompiler (di mana bahasa dasar sebagian besar tidak relevan) mendorong pergeseran dari set instruksi CISC (yang sebagian besar dirancang untuk dikodekan oleh manusia) ke set instruksi RISC (yang sebagian besar dirancang untuk dikodekan oleh kompiler.)

rockets4kids
sumber
5

Keluarga Motorola 68000 memperkenalkan beberapa metode alamat otomatis yang membuat menyalin data melalui cpu sangat efisien dan ringkas.

[Contoh yang diperbarui]

ini adalah beberapa kode c ++ yang mempengaruhi 68000 assembler

while(someCondition)
    destination[destinationOffset++] = source[sourceOffset++]

diimplementasikan dalam assembler konvensional (pseudocode, saya lupa perintah 68000 assembler)

adressRegister1 = source
adressRegister2 = destination
while(someCondition) {
    move akku,(adressRegister1)
    move (adressRegister2), akku
    increment(adressRegister1, 1)
    increment(adressRegister2, 1)
}

dengan adressmode baru itu menjadi sesuatu yang serupa

adressRegister1 = source
adressRegister2 = destination
while(someCondition) {
    move akku,(adressRegister1++)
    move (adressRegister2++), akku
}

hanya dua instruksi per loop, bukan 4.

k3b
sumber
1
Bagaimana ini dipengaruhi oleh konvensi bahasa tertentu?
Gayus
lihat contoh yang diperbarui
k3b
Ah, mengingatkan saya pada optimasi loop DBxx di 68010.
Gayus
7
Sebenarnya, saya pikir Anda memiliki ini mundur. Auto [in | de] crement addressing adalah bagian dari set instruksi PDP-11, yang kemungkinan mempengaruhi desain C.
TMN
5

Mainframe seri Z IBM, adalah keturunan dari IBM 360 dari tahun 1960-an.

Ada beberapa instruksi yang ditujukan khusus untuk mempercepat program COBOL dan Fortran. Contoh klasik adalah BXLE- "Cabang pada Indeks Rendah Atau Setara" yang sebagian besar dari forloop Fortran atau COBOL PERFORM VARYING x from 1 by 1 until x > ndienkapsulasi dalam satu instruksi.

Ada juga seluruh keluarga instruksi desimal dikemas untuk mendukung aritmatika desimal titik tetap yang umum dalam program COBOL.

James Anderson
sumber
Saya pikir maksud Anda keturunan .
Clockwork-Muse
@ X-Zero - oops! Dini hari, tidak cukup kopi dalam sistem dll .......
James Anderson
1
Yang lebih menarik adalah instruksi blok-ulang TI 32050 DSP. Operandnya adalah alamat instruksi berikut yang terakhir dalam loop; memuat register loop-count dan kemudian melakukan instruksi blok-repeat akan menyebabkan instruksi hingga (tetapi tidak termasuk) target diulangi beberapa kali. Sangat mengingatkan pada DOloop FORTRAN .
supercat
@supercat Setiap DSP yang layak namanya mencakup tiga fitur: loop nol-overhead, satu instruksi ganda-terakumulasi, dan mode pengalamatan agak terbalik dari beberapa jenis. Hampir setiap algoritma DSP yang dikenal oleh Man menggunakan loop. Dua algoritma yang paling umum adalah filter FIR, yang merupakan loop di sekitar akumulasi multiply, dan FFT, di mana pengalamatan bit-reversed sangat penting. Banyak DSP menyertakan operasi kupu-kupu FFT satu-instruksi radix-2, atau dual-multiply / add yang dapat digunakan untuk membuat kupu-kupu satu-instruksi.
John R. Strohm
@ JohnR.Strohm: Setiap DSP yang saya lihat mencakup akumulasi berulang-gandakan, tetapi tidak semuanya menyertakan loop nol overhead yang lebih umum. Sebenarnya, saya tidak begitu yakin mengapa loop seperti itu harus dianggap hanya fitur "DSP", karena mereka akan berguna dalam banyak kode "prosesor konvensional" juga.
supercat
3

Intel CPU awal memiliki fitur-fitur berikut, banyak dari mereka sekarang usang dalam mode 64-bit:

  • MASUKKAN, MENINGGALKAN, dan MENGEMBALIKAN instruksi [manual awal yang secara eksplisit mengatakan itu diperkenalkan untuk bahasa terstruktur blok, misalnya Pascal, yang mendukung prosedur bersarang]
  • instruksi untuk mempercepat aritmatika BCD (AAA, AAM, dll.); juga dukungan BCD di x87
  • Instruksi JCXZ dan LOOP untuk menerapkan loop terhitung
  • INTO, untuk menghasilkan jebakan pada aritmatika meluap (misalnya, dalam Ada)
  • XLAT untuk pencarian tabel
  • TERIKAT untuk memeriksa batas array

Tanda bendera, ditemukan dalam register status banyak CPU, ada untuk dengan mudah melakukan aritmatika yang ditandatangani DAN tidak ditandatangani.

Set instruksi SSE 4.1 memperkenalkan instruksi untuk pemrosesan string, baik yang dihitung maupun yang diakhiri nol (PCMPESTR, dll.)

Juga, saya dapat membayangkan bahwa sejumlah fitur tingkat sistem dirancang untuk mendukung keamanan kode yang dikompilasi (pengecekan batas segmen, gerbang panggilan dengan penyalinan parameter, dll.)

zvrba
sumber
3

Beberapa prosesor ARM, terutama yang ada di perangkat seluler, termasuk (d) ekstensi Jazelle, yang merupakan interpreter JVM perangkat keras; itu mengartikan bytecode Java secara langsung. Jazelle-aware JVM dapat menggunakan perangkat keras untuk mempercepat eksekusi dan menghilangkan banyak JIT, tetapi mundur ke perangkat lunak VM masih dipastikan jika bytecode tidak dapat diartikan pada chip.

Prosesor dengan unit tersebut termasuk instruksi BXJ, yang menempatkan prosesor dalam "mode Jazelle" khusus, atau jika mengaktifkan unit telah gagal, itu hanya ditafsirkan sebagai instruksi cabang normal. Unit menggunakan kembali register ARM untuk menahan status JVM.

Penerus teknologi Jazelle adalah ThumbEE

usoban
sumber
2

Sejauh yang saya tahu ini lebih umum di masa lalu.

Ada sesi pertanyaan di mana James Gosling mengatakan bahwa ada orang yang mencoba membuat perangkat keras yang dapat menangani bytecode JVM dengan lebih baik, tetapi kemudian orang-orang ini akan menemukan cara untuk melakukannya dengan "x" umum intel x86 umum (mungkin mengkompilasi bytecode dalam beberapa cara pintar).

Dia menyebutkan bahwa ada keuntungan dalam menggunakan chip populer generik (seperti intel) karena memiliki perusahaan besar yang mengeluarkan sejumlah besar uang pada produk tersebut.

Video ini layak untuk dicoba. Dia membicarakan hal ini pada menit 19 atau 20.

Pedro Henrique A. Oliveira
sumber
2

Saya melakukan pencarian halaman cepat dan tampaknya tidak ada yang menyebutkan CPU yang dikembangkan secara khusus untuk mengeksekusi Forth . The bahasa pemrograman Forth adalah tumpukan berbasis, kompak, dan digunakan dalam sistem kontrol.

Paddy3118
sumber
2

The Intel iAPX CPU secara khusus dirancang untuk bahasa OO. Tapi tidak cukup berhasil.

The iAPX 432 ( intel Lanjutan Processor arsitektur ) adalah pertama desain mikroprosesor 32-bit Intel, diperkenalkan pada tahun 1981 sebagai set dari tiga sirkuit terpadu. Itu dimaksudkan untuk menjadi desain utama Intel untuk tahun 1980-an, menerapkan banyak fitur multitasking dan manajemen memori yang canggih. Desain karena itu disebut sebagai Micromainframe ...

IAPX 432 "dirancang untuk diprogram sepenuhnya dalam bahasa tingkat tinggi" , dengan Ada menjadi yang utama dan mendukung pemrograman berorientasi objek dan pengumpulan sampah langsung dalam perangkat keras dan mikrokode . Dukungan langsung untuk berbagai struktur data juga dimaksudkan untuk memungkinkan sistem operasi modern untuk iAPX 432 diimplementasikan menggunakan kode program yang jauh lebih sedikit daripada untuk prosesor biasa. Properti dan fitur ini menghasilkan desain perangkat keras dan mikrokode yang jauh lebih kompleks daripada kebanyakan prosesor pada zaman itu, terutama mikroprosesor.

Menggunakan teknologi semikonduktor pada zamannya, para insinyur Intel tidak dapat menerjemahkan desain menjadi implementasi pertama yang sangat efisien. Seiring dengan kurangnya optimasi dalam kompiler Ada prematur, ini berkontribusi pada sistem komputer yang agak lambat tapi mahal, melakukan benchmark khas sekitar 1/4 kecepatan chip 80286 baru pada frekuensi clock yang sama (pada awal 1982).

Kesenjangan kinerja awal untuk profil yang agak rendah dan harga rendah 8086 mungkin merupakan alasan utama mengapa rencana Intel untuk menggantikan yang terakhir (kemudian dikenal sebagai x86) dengan iAPX 432 gagal. Meskipun para insinyur melihat cara untuk meningkatkan desain generasi berikutnya, arsitektur kapabilitas iAPX 432 kini telah mulai dianggap lebih sebagai overhead implementasi daripada sebagai dukungan penyederhanaan yang seharusnya.

Proyek iAPX 432 adalah kegagalan komersial untuk ...

hanya lewat saja
sumber
Membaca kertas, sepertinya banyak aspek desain bisa berguna dalam kerangka kerja berorientasi objek seperti yang populer saat ini. Arsitektur yang menggunakan kombinasi objek-id 32-bit dan offset 32-bit dalam banyak kasus dapat menawarkan kinerja caching yang lebih baik daripada arsitektur di mana id objek semuanya 64 bit (dalam kebanyakan kasus, aplikasi yang akan menggunakan miliaran objek akan lebih baik dilayani dengan memiliki lebih banyak, yang lebih besar; satu yang akan menyimpan miliaran byte dalam satu objek akan lebih baik disajikan membagi itu menjadi objek yang lebih kecil.
supercat
1

68000 memiliki MOVEM yang paling cocok untuk mendorong banyak register ke stack dalam satu instruksi yang merupakan apa yang diharapkan banyak bahasa.

Jika Anda melihat MOVEM (MOVE Multiple) sebelumnya JSR (Jump SubRoutine) di seluruh kode, maka Anda umumnya tahu bahwa Anda berurusan dengan kode yang dipenuhi C.

MOVEM diizinkan untuk penambahan otomatis register tujuan yang memungkinkan setiap penggunaan untuk melanjutkan penumpukan pada tujuan, atau menghapus dari tumpukan jika terjadi penurunan otomatis.

http://68k.hax.com/MOVEM

Myztry
sumber
1

Arsitektur AVR Atmel sepenuhnya dirancang dari bawah ke atas agar sesuai untuk pemrograman dalam C. Sebagai contoh, catatan aplikasi ini menguraikan lebih jauh.

IMO ini terkait erat dengan jawaban yang sangat baik dari rockets4kids , dengan PIC16-s awal dikembangkan untuk pemrograman assembler langsung (total 40 instruksi), dengan keluarga kemudian menargetkan C.

Vorac
sumber
1

Ketika 8087 numerik coprocessor dirancang, itu cukup umum bagi bahasa untuk melakukan semua matematika floating-point menggunakan tipe presisi tertinggi, dan hanya membulatkan hasilnya ke presisi yang lebih rendah ketika menugaskannya ke variabel presisi yang lebih rendah. Dalam standar C asli, misalnya, urutannya:

float a = 16777216, b = 0.125, c = -16777216;
float d = a+b+c;

akan mempromosikan adan buntuk double, tambahkan mereka, mempromosikan cuntuk double, menambah, dan kemudian menyimpan hasilnya dibulatkan menjadi float. Meskipun dalam banyak kasus akan lebih cepat bagi kompiler untuk menghasilkan kode yang akan melakukan operasi langsung pada tipe float, itu lebih mudah untuk memiliki satu set rutin floating-point yang akan beroperasi hanya pada tipe double, bersama dengan rutinitas untuk mengkonversi ke / dari float, daripada memiliki rangkaian rutin terpisah untuk menangani operasi pada floatdan double. The 8087 dirancang di sekitar pendekatan aritmatika, melakukan semua operasi aritmatika menggunakan tipe floating-point 80-bit [80 bit mungkin dipilih karena:

  1. Pada banyak prosesor 16-dan 32-bit, lebih cepat bekerja dengan mantissa 64-bit dan eksponen terpisah daripada bekerja dengan nilai yang membagi byte antara mantissa dan eksponen.

  2. Sangat sulit untuk melakukan perhitungan yang akurat dengan ketepatan penuh dari jenis numerik yang digunakan; jika seseorang mencoba misalnya menghitung sesuatu seperti log10 (x), lebih mudah dan lebih cepat untuk menghitung hasil yang akurat dalam 100ulp dari jenis 80-bit daripada menghitung hasil yang akurat dalam 1ulp dari 64-bit ketik, dan membulatkan hasil sebelumnya ke presisi 64-bit akan menghasilkan nilai 64-bit yang lebih akurat daripada yang terakhir.

Sayangnya, versi bahasa yang akan datang mengubah semantik bagaimana seharusnya tipe floating-point; sementara semantik 8087 akan sangat baik jika bahasa mendukungnya secara konsisten, jika fungsi f1 (), f2 (), dll. jenis kembali float, banyak penulis kompiler akan mengambil sendiri untuk membuat long doublealias untuk jenis ganda 64-bit daripada tipe 80-bit kompiler (dan tidak menyediakan cara lain untuk membuat variabel 80-bit), dan untuk secara sewenang-wenang mengevaluasi sesuatu seperti:

double f = f1()*f2() - f3()*f4();

dengan salah satu cara berikut:

double f = (float)(f1()*f2()) - (extended_double)f3()*f4();
double f = (extended_double)f1()*f2() - (float)(f3()*f4());
double f = (float)(f1()*f2()) - (float)(f3()*f4());
double f = (extended_double)f1()*f2() - (extended_double)f3()*f4();

Perhatikan bahwa jika f3 dan f4 masing-masing mengembalikan nilai yang sama dengan f1 dan f2, ekspresi asli harus jelas mengembalikan nol, tetapi banyak dari ekspresi terakhir mungkin tidak. Hal ini menyebabkan orang-orang mengutuk "ketepatan ekstra" dari 8087 meskipun formulasi terakhir umumnya akan lebih unggul dari yang ketiga dan - dengan kode yang menggunakan tipe ganda diperpanjang dengan tepat - jarang akan lebih rendah.

Pada tahun-tahun berikutnya, Intel telah menanggapi tren bahasa (IMHO disayangkan) ke arah memaksa hasil antara dibulatkan ke presisi operan dengan merancang prosesor mereka yang kemudian untuk mendukung perilaku itu, dengan merugikan kode yang akan mendapat manfaat dari menggunakan yang lebih tinggi presisi pada perhitungan menengah.

supercat
sumber
Perhatikan bahwa Anda sudah mendapat jawaban (di atas ) di pos ini. Apakah mereka jawaban yang bisa / harus digabung menjadi satu?
@MichaelT: Saya kira tidak - satu mencakup desain tumpukan, dan lainnya mencakup semantik titik-mengambang.
supercat
Hanya memastikan. Secara pribadi, saya percaya bahwa adalah mungkin untuk membuat satu, jawaban yang lebih kuat (menggunakan header untuk memisahkan bagian-bagian), tetapi itulah pendapat saya. Anda mungkin ingin tetap menggunakan tajuk untuk mengidentifikasi dengan jelas di bagian atas apa yang dijawab oleh setiap bagian jawaban ( ## How the stack changed the processordan ## How floating point changed the processor) sehingga orang dapat memahami pikirannya ketika membacanya dan kecil kemungkinannya untuk berpikir bahwa Anda linglung dalam menjawab atau memposting ulang jawaban yang sama (mirip).
@MichaelT: Kedua jawaban itu cukup terpisah sehingga saya pikir mereka harus dipilih secara terpisah. Meskipun 80486 menyerap fungsi yang sebelumnya dilakukan oleh 8087/80287/80387, 8086 dan 8087 dirancang sebagai chip terpisah dengan arsitektur yang hampir independen. Meskipun keduanya menjalankan kode dari aliran instruksi umum, yang ditangani dengan memiliki 8086 memperlakukan urutan byte tertentu sebagai permintaan untuk menghasilkan alamat membaca / menulis permintaan sambil mengabaikan bus data, dan memiliki 8.087 mengabaikan semua hal lain yang sedang terjadi.
supercat