mengapa arsitektur CPU menggunakan register flag (keuntungan?)

15

Beberapa CPU memiliki register flag (ARM, x86, ...), lainnya tidak (MIPS, ...). Apa keuntungan dari memiliki instruksi CMP untuk memperbarui register bendera diikuti oleh instruksi cabang daripada menggunakan register nol dan cabang bersyarat untuk memeriksa tanda, meluap dll?

dunia model
sumber

Jawaban:

11

Dalam mikro-arsitektur modern dengan register yang mengubah nama biaya implementasi untuk bendera atau tidak, bendera sangat mirip. Perbedaan utama yang dapat saya pikirkan adalah bahwa beberapa flag menunjukkan karakteristik dari suatu nilai (Apakah nilainya negatif? Apakah nilainya nol? Apakah nilainya memiliki paritas genap atau ganjil?), Sementara beberapa mewakili suatu peristiwa yang terjadi selama operasi sebelumnya (Apakah instruksi add telah dilakukan atau overflow?) Hal ini menyebabkan situasi yang kurang ideal pada MIPS ketika Anda ingin mensimulasikan penambahan 64-bit pada arsitektur 32-bit (atau penambahan 128-bit pada Arsitektur 64-bit.) Pada sebagian besar arsitektur dengan bendera jinjing ada yang istimewaadd-with-carryinstruksi, yang termasuk bendera carry dari instruksi add sebelumnya. Ini membuat simulasi multi-presisi aritmatika relatif murah pada banyak arsitektur dengan register bendera.

Di sisi lain, menguji register N-bit untuk nol atau tidak-nol sebenarnya sangat mahal. Untuk menguji register N-bit untuk nol, Anda perlu melakukan operasi N-bit NOR, yang membutuhkan tingkat logika untuk menghitung. Pada arsitektur dengan flag mendaftar logika tambahan untuk perhitungan nol / tidak-nol pada akhir tahap ALU dapat menyebabkan jam berjalan lebih lambat (atau memaksa ALU untuk memiliki dua operasi siklus.) Untuk alasan ini, saya pikir, beberapa arsitektur, seperti SPARC memiliki dua versi dari setiap operasi aritmatika, satu yang mengatur bendera dan yang lainnya tidak.O(logN)

Tetapi MIPS tidak menyimpan apa pun di sini. Mereka baru saja memindahkan masalah ke tempat lain. Pada MIPS ada branch-on-equalinstruksi. Ini berarti bahwa instruksi cabang harus benar-benar memiliki tahap ALU (termasuk sesuatu seperti xoroperasi bitwise diikuti oleh noruntuk mengurangi turun ke bit sama dengan / tidak sama dengan bit) sebelum menentukan ke arah mana cabang berjalan.

Arsitektur DEC Alpha mencoba memisahkan perbedaan dengan menggunakan trik. DEC Alpha tidak memiliki register bendera, tetapi juga tidak memiliki branch-on-equalinstruksi. Alih-alih instruksi cabang semua melihat keadaan register tujuan umum tunggal. Ada branch-on-zero, branch-on-not-zero, branch-on-less-than-zero, dll Kuncinya adalah bahwa Anda dapat memberikan setiap tujuan umum mendaftarkan bit ke-65 ekstra yang memberitahu Anda apakah lainnya 64 bit adalah nol atau tidak. Ini membuatnya lebih seperti memiliki register bendera: semua instruksi cabang melihat bit tunggal (yang sudah dihitung) untuk membuat keputusan mereka, tetapi sekarang Anda kembali untuk mencari tahu bagaimana menghitung bit indikator ekstra nol selama ALU normal siklus. (Dan Anda masih tidak dapat melakukan aritmatika multi-presisi hanya dengan melihat flag carry dari operasi sebelumnya.)

Logika Pengembaraan
sumber
2
Operasi pengaturan non-CC adalah (dari apa yang saya mengerti) optimasi kompiler , memungkinkan kompiler untuk menjadwalkan instruksi pengaturan CC lebih awal tanpa nilai yang dihancurkan oleh instruksi terakhir. PowerPC750 menempatkan register kondisi (8 register 4-bit) di dekat ujung depan sedemikian sehingga cabang yang diambil mengenai cache instruksi target cabang dan memiliki kondisi yang tersedia cukup awal dapat menyelesaikan cabang yang diambil tanpa penalti. (AT&T CRISP juga mengeksploitasi resolusi cabang awal.) Jumlah kecil dan spesialisasi CC membuat ini lebih praktis.
Paul A. Clayton
Detail: Semua perhitungan flag tidak dibuat sama. Bayangkan CPU Anda memiliki bendera NZVC tradisional. Jika semua instruksi ALU diizinkan untuk memperbarui bendera, Anda harus menempatkan pembuatan bendera setelah penambah / pengurangan dan beberapa muxes. Bendera negatif mudah, hanya MSB, sedangkan bendera Nol mahal dan tergantung pada setiap bit. Sekarang, jika Anda membatasi flag untuk membandingkan (dan uji bit) instruksi, Nol flag dapat dihitung dengan XOR paralel pada operan sumber, tanpa menunggu hasil pengurangan. Menghitung bendera Z setelah penambahan hampir tidak berguna.
TEMLIB
7

1 Dari perspektif ISA

  1. Memiliki instruksi pengujian yang hanya mengatur bendera hanyalah cara untuk mengurangi tekanan register pada arsitektur register yang kelaparan. Jika Anda memiliki cukup register, modifikasi saja salah satunya dan abaikan hasilnya. Trik memiliki register 0 dengan nilai input 0 hanyalah trik enkode yang nyaman ketika Anda memiliki cukup register yang memperbaiki salah satunya menjadi 0 lebih baik daripada meningkatkan jumlah instruksi. Maka nyaman untuk menggunakannya sebagai target juga (ini mengurangi jumlah dependensi salah).

  2. Pengkodean lagi. Jika Anda menyandikan kondisi dalam lompatan, Anda akan memiliki lompatan dengan 3 operan (dua untuk dibandingkan dan target lompatan), dua di antaranya Anda ingin menjadi nilai langsung, yang Anda ingin menjadi sebesar mungkin (lompatan sering memiliki format penyandian sendiri sehingga target dapat menggunakan bit sebanyak mungkin). Atau Anda menjatuhkan kemungkinan.

  3. Menggunakan bendera memberi Anda lebih banyak peluang untuk mengaturnya. Bukan hanya operasi perbandingan yang dapat mengatur bendera, tetapi apa pun yang Anda inginkan. (Dengan peringatan bahwa semakin banyak operasi yang Anda miliki yang mengatur flag, semakin hati-hati Anda harus memastikan bahwa operasi terakhir yang mengatur flag adalah yang Anda inginkan). Jika Anda memiliki bendera, Anda dapat menguji jumlah kondisi (seringkali 16) dikalikan dengan jumlah instruksi yang dapat mengatur bendera (Jika Anda tidak menggunakan bendera, Anda berakhir dengan sebanyak mungkin lompatan bersyarat seperti Anda memiliki hal-hal untuk diuji atau ada hal-hal yang Anda tidak boleh menguji dengan mudah (carry atau overflow misalnya).

2 Dari perspektif pelaksana

  1. Menguji bendera itu mudah dan bisa dilakukan dengan cepat. Semakin rumit pengujian Anda, semakin besar efeknya pada waktu siklus (atau struktur pipa jika Anda menggunakan pipeline). Itu terutama berlaku untuk implementasi yang lebih sederhana, ketika Anda mendapatkan prosesor kelas atas menggunakan semua trik buku ini, efeknya sangat minim.

  2. Memiliki bendera berarti bahwa banyak instruksi memiliki banyak hasil (hasil alami dan masing-masing dari bendera yang dimodifikasi). Dan dari POV mikro-arsitektur, beberapa hasil buruk (Anda harus melacak asosiasi mereka). Ketika Anda hanya memiliki satu set flag, yang memperkenalkan dependensi (tidak dibutuhkan jika flag tersebut tidak digunakan) Anda harus menangani cara atau lainnya. Sekali lagi itu terutama berlaku untuk implementasi yang lebih sederhana, ketika Anda mendapatkan prosesor high-end menggunakan semua trik buku ini, kesulitan tambahan dikerdilkan oleh sisa prosesor.

Pemrogram
sumber
2

Pada mesin 32-bit, instruksi "add-with-carry" yang digunakan sebagai bagian dari urutan penambahan multi-presisi perlu menerima operan senilai 65 bit dan menghitung jumlah 33 bit. Spesifikasi register sumber akan mengidentifikasi dari mana 64 bit operan harus berasal, dan spesifikasi register tujuan akan mengatakan di mana 32 bit lebih rendah dari hasilnya harus pergi, tetapi apa yang harus dilakukan dengan operan "tambahkan satu tambahan" atau bit atas hasilnya? Diperbolehkan untuk menentukan sebagai bagian dari instruksi di mana operan tambahan harus berasal dan ke mana bit hasil tambahan harus cukup bermanfaat, tetapi secara umum tidak begitu berguna untuk membenarkan bidang tambahan dalam opcode. Memiliki "lokasi" yang tetap untuk menangani flag carry dapat sedikit canggung dari perspektif penjadwalan instruksi, tetapi '

Jika seseorang mencoba merancang set instruksi untuk memungkinkan aritmatika multi-presisi tetapi setiap instruksi terbatas pada dua operan 32-bit dan satu operan tujuan 32-bit, seseorang dapat mengimplementasikan "tambah" 64-bit dalam empat instruksi: "set r5 ke 1 jika r0 + r2 akan membawa atau nol sebaliknya; hitung r4 = r1 + r3; hitung r5 = r4 + r5; hitung r4 = r0 + r2 ", tetapi lebih dari itu akan membutuhkan tiga instruksi untuk setiap kata tambahan. Memiliki bendera pembawa tersedia sebagai sumber tambahan dan tujuan mengurangi biaya untuk satu instruksi per kata.

Catatan, btw, yang memiliki bit kontrol mengontrol apakah instruksi memperbarui register bendera dapat memfasilitasi eksekusi out-of-order, karena instruksi yang menggunakan atau memodifikasi bit flag harus mempertahankan urutan mereka relatif satu sama lain, tetapi instruksi yang tidak dapat diatur ulang secara bebas. Diberikan urutan:

ldr  r0,[r1]
add  r0,r0,r2
eors r4,r5,r6

sebuah unit eksekusi dapat dengan mudah mengenali bahwa instruksi ketiga dapat dijalankan tanpa harus menunggu data untuk dibaca [r1], tetapi jika instruksi kedua adalah adds r0,r0,r2itu hanya akan mungkin jika unit eksekusi dapat memastikan bahwa pada saat segala sesuatu mencoba untuk menggunakan bendera, bendera nol akan menyimpan nilai yang ditetapkan dalam instruksi ketiga tetapi bendera carry akan menyimpan nilai dalam instruksi kedua.

supercat
sumber
1
"kontrol bit instruksi apakah instruksi memperbarui register bendera": Tersedia misalnya di PowerPC, SPARC.
TEMLIB
MIPS menggunakan "r5 = r1 + r2; set r6 jika r6 kurang dari r1; r7 = r3 + r4; r5 = R5 + R6;". Beberapa ekstensi SIMD dapat menggunakan perbandingan yang mengatur semua bit ke nol atau satu (yaitu, nol atau -1 dua komplemen integer) untuk menemukan carry dan pengurangan untuk menerapkan carry.
Paul A. Clayton
@ PaulA.Clayton: Saya pikir Anda bermaksud "jika r5 kurang dari r1". Bagaimana MIPS menangani matematika yang lebih lama? Apakah akan membutuhkan tiga, lebih dari tiga, atau kurang dari tiga instruksi per kata?
supercat
@supercat Ya, seharusnya "set r6 jika r5 kurang dari r1"!
Paul A. Clayton
@ PaulA.Clayton: Bagaimana cara menambahkan misalnya dua angka 64-kata (2048-bit) pada MIPS 32-bit? Apakah ada cara yang efisien untuk menangani kiriman masuk dan keluar dari tahap tengah?
supercat
0

Jawaban sederhana ... operasi memori murah cepat yang sama sekali tidak memerlukan penggunaan internal kecuali instruksi itu sendiri. Ini dapat digunakan sebagai tumpukan tumpukan tanpa tumpukan atau sedikit proses, tanpa memori.

SkipBerne
sumber
1
Jawaban ini agak ringan pada detail. Jawaban panjang tidak selalu diperlukan tetapi sesuatu yang lebih sempurna akan menjadi peningkatan yang berbeda.
David Richerby
mengatur bendera atau membandingkan nilai bendera adalah instruksi tunggal tanpa informasi lain dalam bentuk argumen yang akan dimasukkan dalam kode perakitan. flag juga merupakan hasil dari operasi atau pengujian uprocessor dan dapat digunakan secara efisien untuk bercabang. mereka adalah bit aktual yang diaktifkan atau disetel ketika dua nilai dibandingkan dalam register.
SkipBerne