Setiap proyek emulator maupun perluasan CPU menghadapi pilihan rancangan yang tidak punya jawaban tunggal, misalnya cara memodelkan memori atau urutan pekerjaan yang dikerjakan lebih dahulu. Keputusan seperti itu bertahan selama proyek berjalan, sedangkan alasannya mudah hilang dari ingatan. Topik ini menetapkan format catatan keputusan yang memuat konteks, keputusan, alternatif yang ditolak, dan konsekuensinya, lalu mempraktikkannya pada empat keputusan nyata proyek emulator RV32I subset. Berkas contoh yang siap ditiru menutup pembahasan.
Format catatan keputusan#
Trade-off adalah pertukaran antara keuntungan dan kerugian dari beberapa pilihan rancangan, dan keputusan yang diambil dari pertukaran itu layak dicatat karena harganya akan muncul kembali di kemudian hari. Format yang digunakan sepanjang proyek hanya perlu empat bagian, dan urutannya mengikuti cara keputusan lahir.
- Konteks menyatakan masalah yang memaksa keputusan dibuat, lengkap dengan angka yang membuatnya nyata, misalnya alamat stack atau jumlah layanan yang dibutuhkan program uji.
- Keputusan menyatakan pilihan yang diambil dalam satu kalimat tegas, sehingga terbaca tanpa perlu menebak.
- Alternatif yang ditolak memuat pilihan lain yang dipertimbangkan sungguhan beserta alasan penolakannya.
- Konsekuensi menyatakan harga yang dibayar oleh keputusan itu beserta aturan yang menjaganya tetap dapat diterima.
Catatan ditulis pada hari keputusannya dibuat, bukan pada akhir proyek, karena alternatif yang ditolak adalah bagian pertama yang hilang dari ingatan. Format ini tidak menuntut alat khusus, karena satu berkas teks di samping kode proyek sudah cukup. Kekuatan catatannya ada pada disiplin isinya, yaitu setiap keputusan yang punya alternatif serius mendapat satu entri, sedangkan keputusan yang tidak punya alternatif tidak dicatat sama sekali.
Empat keputusan pada proyek emulator#
Tabel berikut meringkas empat keputusan yang lazim muncul ketika emulator RV32I subset dibangun, lengkap dengan alternatif yang ditolak beserta alasan utamanya.
| Keputusan | Alternatif yang ditolak | Alasan penolakan |
|---|---|---|
Memori sebagai dict byte per alamat | bytearray berukuran tetap | ruang alamat 32 bit tidak mungkin dialokasikan penuh, sedangkan program uji hanya menyentuh segelintir alamat |
| Pseudo-instruksi ditafsirkan langsung dari teks | assembler penuh lalu decode bit | tahap assembler menggandakan pekerjaan sebelum satu instruksi pun terbukti berjalan |
| ecall mendukung empat layanan cetak dan keluar | meniru seluruh layanan RARS | layanan masukan membuat keluaran pengujian bergantung pada ketikan sehingga tidak dapat direproduksi |
Register file sebagai list berisi 32 slot | dict dengan kunci nama register | dua nama seperti a0 dan x10 menunjuk register yang sama, sehingga dict nama menuntut normalisasi tambahan |
Keempat baris menunjukkan pola yang sama, yaitu alternatif yang ditolak bukan pilihan yang keliru, melainkan pilihan yang harganya tidak sesuai dengan tujuan proyek. bytearray adalah pilihan yang tepat untuk mesin yang meniru memori fisik, tetapi proyek ini meniru ruang alamat yang jarang terpakai. Assembler penuh adalah pekerjaan yang layak, tetapi ia menunda bukti pertama bahwa mesin berjalan. Layanan RARS yang lengkap berguna untuk program interaktif, sedangkan program uji membutuhkan keluaran yang dapat direproduksi. Setiap keputusan pada tabel membayar harganya secara terbuka, mulai dari akses memori yang lebih lambat, cakupan encoding yang sengaja ditunda, program yang berhenti pada layanan yang belum didukung, hingga tabel penerjemahan nama register yang harus dijaga.
Alasan konkret, bukan selera#
Sebuah alasan layak disebut konkret apabila ia menunjuk kriteria yang dapat diperiksa, misalnya jumlah tahap sebelum uji pertama, kebutuhan memori program uji, reproduksi keluaran, atau aturan penamaan register. Alasan semacam itu dapat dibantah dengan data baru, dan kemampuan dibantah itulah yang membuat keputusan dapat direvisi secara jujur. Sebaliknya, frasa seperti lebih elegan atau lebih bersih tidak dapat diperiksa dan tidak dapat dibantah, sehingga tidak menambah pengetahuan apa pun bagi yang membaca ulang catatan itu.
Alasan konkret juga memisahkan keputusan dari selera. Selera berhenti pada perbedaan rasa, sedangkan keputusan rancangan membawa harga yang dapat dinyatakan, misalnya lima pencarian tabel untuk satu akses lw atau satu tahap assembler yang harus dibayar. Ketika konsekuensinya dinyatakan terbuka, pembaca catatan dapat menilai sendiri apakah harga itu masih masuk akal untuk proyek lain yang berbeda tujuannya. Catatan yang hanya memuat keuntungan tidak berbeda dari promosi, sedangkan catatan yang memuat harga akan tetap berguna setelah keputusannya sendiri digantikan.
Berkas keputusan contoh#
Praktik yang dianjurkan berupa satu berkas keputusan untuk satu proyek, dengan entri bernomor seperti D01 dan D02 agar mudah dirujuk. Entri ditambahkan pada hari keputusannya dibuat, dan entri lama yang digantikan tidak dihapus, melainkan diberi tanda. Berkas berikut memuat empat entri pertama dari proyek emulator pada tabel sebelumnya, dalam bentuk yang siap ditiru.
# Catatan Keputusan Rancangan Proyek Emulator
Entri ditambahkan pada hari keputusannya dibuat. Keputusan lama tidak dihapus,
tetapi ditandai digantikan oleh entri yang lebih baru, sehingga jejaknya tetap
terbaca. Setiap entri memuat konteks, keputusan, alternatif yang ditolak, dan
konsekuensi.
## D01. Memori sebagai dict byte per alamat
- Konteks: program uji hanya menyentuh segelintir alamat, sedangkan stack
diletakkan di 0x10000, jauh dari kode dan data.
- Keputusan: memori dimodelkan sebagai `dict` yang memetakan alamat byte ke
nilai byte, dan alamat yang belum pernah ditulis dibaca sebagai 0.
- Alternatif yang ditolak: `bytearray` berukuran tetap. Ruang alamat 32 bit
tidak mungkin dialokasikan penuh, sehingga ukuran tetap menuntut keputusan
kapasitas yang tidak diminta oleh cakupan proyek apa pun.
- Konsekuensi: satu `lw` menuntut lima pencarian alamat terpisah, sehingga
akses memori lebih lambat daripada larik byte yang berdampingan. Kecepatan
bukan kriteria proyek ini, maka harga itu dapat dibayar.
## D02. Pseudo-instruksi ditafsirkan langsung dari teks
- Konteks: tujuan pertama proyek adalah menjalankan perulangan dan pemanggilan
fungsi dengan keluaran yang benar, bukan mempelajari encoding.
- Keputusan: parser membaca mnemonic beserta operand teksnya, lalu menafsirkan
pseudo-instruksi langsung tanpa menerjemahkan program menjadi kata 32 bit.
- Alternatif yang ditolak: tahap assembler penuh yang menghasilkan kata
instruksi 32 bit, disusul decoder bit demi bit pada fetch. Tahap itu
menggandakan pekerjaan sebelum satu instruksi pun terbukti berjalan.
- Konsekuensi: proyek ini tidak membuktikan pemahaman encoding RV32I, dan `li`
dengan immediate besar tidak pernah memunculkan bentuk pasangan `lui` dan
`addi` aslinya. Pemahaman encoding dinyatakan sebagai cakupan yang sengaja
ditunda.
## D03. ecall mendukung empat layanan
- Konteks: program uji yang direncanakan hanya mencetak hasil dan keluar.
- Keputusan: layanan 1 untuk bilangan bertanda, 4 untuk string, 11 untuk satu
karakter, dan 10 untuk keluar. Layanan lain menghentikan program dengan
pesan yang menyebut nomornya.
- Alternatif yang ditolak: meniru seluruh layanan RARS. Layanan masukan
membuat keluaran bergantung pada ketikan pada saat pengujian, sehingga
perbandingan otomatis dengan oracle tidak dapat direproduksi.
- Konsekuensi: program assembly yang menggunakan layanan lain berhenti lebih
awal. Pesan errornya dianggap keluaran yang sah, bukan kerusakan emulator.
## D04. Register file sebagai list berisi 32 slot
- Konteks: instruksi menyebut register lewat field 5 bit, sedangkan assembly
menulisnya sebagai nama seperti `a7` atau `x10`.
- Keputusan: register file berupa `list` berisi 32 slot bernomor, dengan
penjagaan satu baris yang membuat slot 0 selalu terbaca nol.
- Alternatif yang ditolak: `dict` dengan kunci nama register. Dua nama dapat
menunjuk register yang sama, misalnya `a0` dan `x10`, sehingga dict nama
menuntut normalisasi tambahan pada setiap akses.
- Konsekuensi: tabel konstanta penerjemahan nama ke nomor tetap diperlukan
pada lapisan parser, dan ia menjadi satu-satunya tempat yang menyimpan
aturan penamaan.Bagian konsekuensi pada entri D02 patut dicontoh, karena catatan itu menyatakan dengan jujur apa yang tidak dibuktikan oleh proyek. Pernyataan semacam ini berguna pada validasi akhir, ketika batas cakupan perlu dinilai terhadap tanda selesai yang ditetapkan, dan batas itu sudah tertulis lebih dahulu tanpa perlu menggali ulang alasan dari kode. Nomor entri juga memudahkan rujukan dua arah, misalnya komentar pada berkas parser yang menyebut D02 pada baris yang menafsirkan pseudo-instruksi, sehingga kode dan catatannya saling menjelaskan. Entri D04 memperlihatkan sisi lain, yaitu konsekuensi yang berupa pekerjaan kecil yang harus dijaga, bukan kerugian yang besar.
Kesalahan umum#
- Menulis catatan keputusan setelah proyek berakhir. Alternatif yang ditolak adalah bagian pertama yang hilang dari ingatan, dan konsekuensinya menyusul tidak lama kemudian. Perbaikannya berupa entri yang ditulis pada hari keputusannya dibuat, walau setiap bagian baru berupa satu kalimat.
- Mengisi alasan dengan kata selera. Frasa seperti lebih elegan atau lebih bersih tidak dapat diperiksa dan tidak dapat dibantah, sehingga catatannya tidak menambah apa pun. Perbaikannya berupa kriteria terukur, misalnya jumlah tahap sebelum uji pertama atau jumlah pencarian tabel untuk satu akses memori.
- Menghapus entri lama ketika keputusan berubah. Jejak keputusan menjadi putus, dan alasan keputusan lama hilang bersama entrinya, sehingga pertanyaan tentang mengapa pilihan lama gagal tidak dapat dijawab lagi oleh catatan. Perbaikannya berupa tanda digantikan pada entri lama, disusul entri baru dengan nomor berikutnya.
- Mencatat keputusan yang tidak punya alternatif nyata. Pilihan bahasa yang ditentukan ketersediaan runtime bukan trade-off, karena tidak ada alternatif yang dipertimbangkan sungguhan. Perbaikannya berupa penahanan diri, yaitu catatan hanya diisi keputusan yang alternatifnya dianggap serius.
Ringkasan#
- Catatan keputusan memuat empat bagian, yaitu konteks, keputusan, alternatif yang ditolak, dan konsekuensi, dan ditulis pada hari keputusannya dibuat.
- Alasan penolakan menunjuk kriteria terukur seperti jumlah tahap sebelum uji pertama atau reproduksi keluaran, bukan selera.
- Entri lama tidak dihapus, melainkan ditandai digantikan, sehingga jejak keputusan tetap terbaca.
- Empat keputusan emulator pada topik ini memperlihatkan harga yang dibayar secara terbuka, mulai dari akses memori yang lebih lambat hingga cakupan encoding yang sengaja ditunda.
Referensi#
- RISC-V Instruction Set Manual — RISC-V International — Spesifikasi RV32I yang menetapkan cakupan instruksi proyek, dasar keputusan tentang mana yang didukung dan mana yang ditunda.
- Computer Systems: A Programmer’s Perspective — Carnegie Mellon — Mendefinisikan Y86-64 sebagai set instruksi sederhana sebelum mengimplementasikannya, contoh keputusan menyempitkan cakupan di awal proyek.