Saya selalu bertanya-tanya mengapa prosesor berhenti di 32 register. Ini adalah bagian mesin yang tercepat, mengapa tidak membuat prosesor yang lebih besar dengan register yang lebih banyak? Bukankah itu berarti lebih sedikit pergi ke RAM?
computer-architecture
Matt Capone
sumber
sumber
Jawaban:
Pertama, tidak semua arsitektur prosesor berhenti di 32 register. Hampir semua arsitektur RISC yang memiliki 32 register terekspos dalam set instruksi sebenarnya memiliki 32 register integer dan 32 register floating point lainnya (jadi 64). (Floating point "add" menggunakan register berbeda dari integer "add".) Arsitektur SPARC memiliki register windows. Pada SPARC Anda hanya dapat mengakses 32 register integer pada satu waktu, tetapi register bertindak seperti tumpukan dan Anda dapat mendorong dan pop register baru 16 sekaligus. Arsitektur Itanium dari HP / Intel memiliki 128 integer dan 128 register floating point yang terekspos dalam set instruksi. GPU modern dari NVidia, AMD, Intel, ARM, dan Imagination Technologies, semuanya memperlihatkan sejumlah besar register dalam file register mereka. (Saya tahu ini benar dari arsitektur NVidia dan Intel, saya tidak begitu akrab dengan set instruksi AMD, ARM dan Imagination, tapi saya pikir file register juga besar di sana.)
Kedua, sebagian besar mikroprosesor modern menerapkan pengubahan nama register untuk menghilangkan serialisasi yang tidak perlu yang disebabkan oleh kebutuhan untuk menggunakan kembali sumber daya, sehingga file register fisik yang mendasarinya dapat lebih besar (96, 128 atau 192 register pada beberapa mesin.) Ini (dan penjadwalan dinamis) menghilangkan beberapa perlu bagi kompiler untuk menghasilkan begitu banyak nama register yang unik, sambil tetap menyediakan file register yang lebih besar untuk penjadwal.
Ada dua alasan mengapa mungkin sulit untuk lebih meningkatkan jumlah register yang terekspos dalam set instruksi. Pertama, Anda harus dapat menentukan pengidentifikasi register dalam setiap instruksi. 32 register membutuhkan specifier register 5 bit, sehingga instruksi 3-alamat (umum pada arsitektur RISC) menghabiskan 15 dari 32 bit instruksi hanya untuk menentukan register. Jika Anda meningkatkannya menjadi 6 atau 7 bit, maka Anda akan memiliki lebih sedikit ruang untuk menentukan opcodes dan konstanta. GPU dan Itanium memiliki instruksi yang jauh lebih besar. Instruksi yang lebih besar dikenakan biaya: Anda perlu menggunakan lebih banyak memori instruksi, sehingga perilaku cache instruksi Anda kurang ideal.
Alasan kedua adalah waktu akses. Semakin besar Anda membuat memori semakin lambat untuk mengakses data dari itu. (Hanya dalam hal fisika dasar: data disimpan dalam ruang 2 dimensi, jadi jika Anda menyimpan bit, jarak rata-rata ke bit tertentu adalah .) File register hanyalah sebuah memori multi-porting kecil, dan salah satu kendala untuk membuatnya lebih besar adalah bahwa pada akhirnya Anda harus mulai mencatat mesin Anda lebih lambat untuk mengakomodasi file register yang lebih besar. Biasanya dalam hal kinerja total ini adalah kerugian. O ( √n O(n−−√)
sumber
Hanya dua alasan lagi untuk membatasi jumlah register:
sumber
Banyak kode yang memiliki banyak akses memori (30% adalah angka tipikal). Dari itu, biasanya sekitar 2 / 3rds adalah akses baca dan 1 / 3rds adalah akses tulis. Ini bukan karena kehabisan register sebanyak mengakses array, mengakses variabel anggota objek dll.
HAS ini harus dilakukan dalam memori (atau cache data) karena bagaimana C / C ++ dibuat (semua yang Anda bisa dapatkan pointer harus memiliki alamat agar berpotensi disimpan dalam memori). Jika kompiler dapat menebak bahwa Anda tidak akan menulis ke variabel mau tak mau menggunakan trik pointer tidak langsung gila itu akan menempatkan mereka dalam register, dan ini berfungsi baik untuk variabel fungsi tetapi tidak untuk yang dapat diakses secara global (umumnya, semua yang keluar dari malloc ()) karena pada dasarnya tidak mungkin untuk menebak bagaimana keadaan global akan berubah.
Karena itu, kompiler tidak dapat melakukan apa pun dengan lebih dari 16 register penggunaan umum. Itulah sebabnya semua arsitek terkenal memiliki sebanyak itu (ARM memiliki 16).
MIPS dan RISC lainnya cenderung memiliki 32 karena tidak terlalu sulit untuk memiliki banyak register - biayanya cukup rendah sehingga sedikit "mengapa tidak?". Lebih dari 32 sebagian besar tidak berguna dan memiliki kelemahan membuat file register lebih lama diakses (masing-masing dua kali lipat dalam jumlah register berpotensi menambah lapisan multiplexer tambahan yang menambah sedikit keterlambatan ...). Ini juga membuat instruksi sedikit lebih lama rata-rata - yang berarti bahwa ketika menjalankan jenis program yang bergantung pada bandwidth memori instruksi, register tambahan Anda sebenarnya memperlambat Anda!
Jika CPU Anda tidak berurutan dan tidak melakukan pengubahan nama register dan Anda mencoba melakukan banyak operasi per siklus (lebih dari 3), maka secara teori Anda membutuhkan lebih banyak register karena jumlah operasi Anda per siklus meningkat. Inilah sebabnya mengapa Itanium memiliki begitu banyak register! Namun dalam praktiknya, selain dari angka-angka-mengambang-titik atau kode berorientasi SIMD (yang sangat bagus di Itanium), sebagian besar kode akan memiliki banyak memori yang dibaca / ditulis dan melompat yang membuat mimpi ini lebih dari-3 ops per siklus tidak mungkin (terutama dalam perangkat lunak berorientasi server seperti database, kompiler, eksekusi bahasa tingkat tinggi seperti javascript, emulasi dll ...). Inilah yang menenggelamkan Itanium.
Itu semua bermuara pada perbedaan antara perhitungan dan eksekusi!
sumber
Siapa yang memberi tahu Anda bahwa prosesor selalu memiliki 32 register? x86 memiliki 8, ARM 32-bit dan x86_64 memiliki 16, IA-64 memiliki 128, dan banyak lagi angka lainnya. Anda dapat melihatnya di sini . Bahkan MIPS, PPC atau arsitektur apa pun yang memiliki 32 register tujuan umum dalam set instruksi, jumlahnya jauh lebih besar dari 32 karena selalu ada register flag (jika ada), register kontrol ... tidak termasuk register yang diganti nama dan register perangkat keras
Semuanya ada harganya. Semakin besar jumlah register, semakin banyak pekerjaan yang Anda miliki saat melakukan pengalihan tugas, semakin banyak ruang yang Anda butuhkan dalam pengkodean instruksi. Jika Anda memiliki lebih sedikit register, Anda tidak perlu menyimpan dan mengembalikan banyak ketika menelepon dan kembali dari fungsi atau beralih tugas dengan imbalan kurangnya register dalam beberapa kode komputasi-luas
Selain itu, semakin besar file register, semakin mahal dan kompleks. SRAM adalah RAM tercepat dan termahal sehingga hanya digunakan dalam cache CPU. Tapi itu masih jauh lebih murah dan memakan waktu lebih sedikit daripada file register dengan kapasitas yang sama.
sumber
Sebagai contoh, prosesor Intel yang khas memiliki "integer" 16 resmi dan 16 register vektor. Namun pada kenyataannya, ada banyak lagi: Prosesor menggunakan "register renaming". Jika Anda memiliki instruksi reg3 = reg1 + reg2, Anda akan memiliki masalah jika instruksi lain menggunakan reg3 belum selesai - Anda tidak dapat menjalankan instruksi baru jika menimpa reg3 sebelum telah dibaca oleh instruksi sebelumnya.
Karena itu ada sekitar 160 register nyata . Jadi instruksi sederhana di atas diubah menjadi "regX = reg1 + reg2, dan ingat bahwa regX berisi reg3". Tanpa mengganti nama register, eksekusi yang tidak benar akan benar-benar mati.
sumber
Saya bukan seorang insinyur listrik, tetapi saya pikir kemungkinan lain untuk alasan membatasi jumlah register, adalah routing. Ada jumlah unit aritmatika yang terbatas, dan mereka harus dapat mengambil input dari setiap register, dan output ke setiap register. Ini terutama benar ketika Anda memiliki program pipelined yang dapat menjalankan banyak instruksi per siklus.
Versi sederhana dari ini akan memiliki kompleksitas , membuat peningkatan jumlah register tidak dapat diabaikan, atau membutuhkan perancangan ulang perutean ke sesuatu yang jauh lebih rumit untuk merutekan semuanya dengan kompleksitas yang lebih baik.O(n2)
Saya mendapat ide untuk jawaban ini dari menonton beberapa pembicaraan Ivan Godard pada CPU Mill. Bagian dari inovasi Mill CPU adalah bahwa Anda tidak dapat menampilkan ke register sewenang-wenang - semua output didorong ke tumpukan register atau "sabuk", yang dengan demikian mengurangi masalah perutean, karena Anda selalu tahu kemana output akan pergi. Perhatikan bahwa mereka masih memiliki masalah perutean untuk mendapatkan register input ke unit aritmatika.
Lihat Arsitektur CPU Mill - the Belt (2 dari 9) untuk pernyataan masalah, dan solusi Mill.
sumber
Adapun MIPS ISA, Hennessy and Patterson, Computer Organisation and Design edisi ke-4 hlm. 176, jawab pertanyaan spesifik ini secara langsung:
sumber