Mengapa Membangun Komputer

Manfaat menaiki lapisan abstraksi komputer sendiri dan hal yang disembunyikan oleh tiap lapisan.

Daftar isi

Topik ini menjelaskan lapisan abstraksi (abstraction layer), yaitu cara kerja komputer disusun berlapis sehingga setiap lapisan menyembunyikan rincian lapisan di bawahnya di balik antarmuka yang tetap. Pembahasan mencakup mekanisme penyembunyian tersebut, keuntungan dan biayanya, serta contoh nyata berupa satu nilai yang dilihat dari beberapa lapisan sekaligus. Hasil akhirnya adalah keputusan yang disertai alasan untuk menaiki lapisan demi lapisan ketika membangun komputer, bukan sekadar mengikuti urutan.

Lapisan abstraksi sebagai kontrak#

Lapisan abstraksi adalah batas kerja antara dua bagian sistem. Bagian di atas batas hanya boleh memanggil antarmuka yang ditawarkan, sedangkan bagian di bawah batas bebas mengubah implementasinya sepanjang antarmuka itu tidak berubah. Kata kuncinya adalah antarmuka yang tetap, bukan implementasinya.

Fungsi pengurutan pada sebuah pustaka dapat ditulis ulang dengan algoritma yang sama sekali berbeda, dan seluruh program pemanggil tetap berjalan, karena nama, parameter, dan perilaku yang dijanjikan tidak berubah. Prinsip yang sama berlaku di bawah bahasa pemrograman. Pernyataan penjumlahan pada bahasa tingkat tinggi diterjemahkan menjadi instruksi mesin, instruksi mesin dieksekusi oleh rangkaian aritmetika, dan rangkaian itu dibangun dari gerbang logika. Setiap tingkat hanya berbicara dengan tingkat tepat di bawahnya, tidak lebih.

Sifat bertingkat inilah yang membuat komputer dapat dibangun oleh manusia. Tanpa lapisan, satu orang harus memahami jutaan transistor untuk menulis program penghitung kata sederhana. Dengan lapisan, penulis aplikasi menganggap bahasa pemrograman sudah jadi, perancang bahasa menganggap prosesor sudah jadi, dan perancang prosesor menganggap gerbang logika sudah jadi. Tiap lapisan mengerjakan satu masalah saja, sehingga keseluruhannya menjadi dapat ditangani.

Apa yang disembunyikan tiap lapisan#

Setiap lapisan membawa dua sisi, yaitu antarmuka yang tampak dan rincian yang ditutup. Penulis aplikasi mengetik penjumlahan tanpa pernah melihat rantai penjumlah di dalam ALU (arithmetic logic unit), rangkaian yang menghitung operasi aritmetika dan logika atas nilai multi-bit, yaitu banyak bit sekaligus. Pengguna menyimpan berkas tanpa mengetahui sektor disk mana yang ditulisi. Penulis assembly menargetkan ISA (instruction set architecture), kontrak berupa daftar instruksi yang dipahami prosesor, tanpa mengetahui bentuk rangkaian yang mengeksekusinya. Tabel berikut merangkum sepasang sisi itu untuk beberapa lapisan utama.

LapisanAntarmuka yang diberikanRincian yang disembunyikan
Bahasa pemrogramanpernyataan, fungsi, tipe dataalokasi memori, instruksi mesin
Sistem operasipermintaan layanan (system call), berkas, prosespenjadwalan, peta memori fisik
ISAdaftar instruksi mesin dan registerdatapath (jalur data), sinyal kontrol, clock (denyut pengatur ritme)
Rangkaian aritmetikahasil operasi multi-bitsusunan gerbang, jeda sinyal antargerbang
Gerbang logikakeluaran boolean per kombinasi masukantegangan, transistor

Urutan baris pada tabel itu bergerak dari lapisan paling tinggi ke paling rendah, dan arah yang sama berlaku bagi rincian yang ditutupnya. Perlu ditegaskan bahwa menyembunyikan bukan berarti menghapus. Rantai penjumlah tetap ada, sektor disk tetap ditulisi, dan sinyal kontrol tetap dinyalakan, hanya saja lapisan di atas tidak perlu mengetahuinya untuk tetap bekerja. Kerumitan tidak lenyap oleh abstraksi, melainkan dipindahkan ke tempat yang tepat, yaitu lapisan yang memang bertanggung jawab atas rincian tersebut.

Keuntungan yang diperoleh, biaya yang ditanggung#

Keuntungan pertama lapisan abstraksi berupa kemudahan bernalar. Jumlah hal yang harus dipahami untuk mencapai satu tujuan menyusut menjadi ukuran antarmukanya, bukan ukuran implementasinya. Keuntungan kedua berupa portabilitas. Program yang ditulis di atas antarmuka tetap berjalan pada perangkat keras apa pun yang mengikuti kontrak yang sama, sehingga satu berkas kode sumber yang sama dapat dikompilasi untuk prosesor yang berbeda. Keuntungan ketiga berupa pembagian kerja, karena tiap lapisan dapat dirancang oleh orang yang berbeda pada waktu yang berbeda.

Trade-off, yaitu pertukaran antara keuntungan dan biaya, muncul dari mekanisme yang sama, karena penyembunyian itulah yang memberi kedua sisi tersebut. Setiap lapisan menambah pekerjaan terjemahan saat program berjalan, misalnya fungsi yang memanggil fungsi lain, atau interpreter yang mengeksekusi kode sumber baris demi baris. Rincian yang disembunyikan juga tidak sepenuhnya menghilang dari hasil akhir. Cache, yaitu memori perantara yang jauh lebih cepat daripada memori utama, tidak terlihat oleh bahasa pemrograman, tetapi pola akses memori program menentukan seberapa sering cache terisi dengan benar dan dengan itu menentukan kecepatan program.

Situasi semacam ini disebut kebocoran abstraksi (leaky abstraction), yaitu kondisi ketika rincian yang seharusnya ditutup justru mengubah perilaku lapisan di atasnya. Kebocoran tidak menjadikan abstraksi sia-sia, tetapi menetapkan kewajiban bagi pembangun komputer, yaitu mengetahui apa yang disembunyikan setiap lapisan agar kejutan semacam itu dapat diantisipasi. Karena itu, topik-topik teknis pada jalur ini membuka lapisan yang bersangkutan setiap kali rinciannya menentukan hasil, seperti komplemen dua pada modul Aritmetika.

Satu nilai yang sama dari beberapa lapisan#

Cara paling cepat melihat lapisan bekerja adalah memperhatikan satu nilai dari beberapa sudut sekaligus. Berkas lapisan.py yang menyertai topik ini mengambil satu pola delapan bit, kemudian menampilkannya sebagai bilangan desimal, bilangan bertanda komplemen dua, bilangan biner, bilangan heksadesimal, dan barisan bit terpisah. Jalankan berkasnya dan amati kelima baris keluarannya.

python lapisan.py
# lapisan.py - satu pola bit yang sama dilihat dari beberapa lapisan

pola = "11001010"
desimal = int(pola, 2)

print(f"{'Aplikasi, desimal':<28}: {desimal}")
print(f"{'Aritmetika, komplemen dua':<28}: {desimal - 256}")
print(f"{'Representasi, biner':<28}: {pola}")
print(f"{'Representasi, heksadesimal':<28}: {format(desimal, '02X')}")
print(f"{'Fisika, bit satu per satu':<28}: {' '.join(pola)}")
text Keluaran
Aplikasi, desimal           : 202
Aritmetika, komplemen dua   : -54
Representasi, biner         : 11001010
Representasi, heksadesimal  : CA
Fisika, bit satu per satu   : 1 1 0 0 1 0 1 0

Kelima baris itu menampilkan satu pola yang sama, yaitu 11001010. Pola tersebut dibaca sebagai bilangan tak bertanda bernilai 202, tetapi dibaca sebagai bilangan bertanda komplemen dua bernilai -54. Kedua pembacaan sama benar, karena yang berbeda hanya konvensi lapisan yang menafsirkannya. Perbedaan semacam ini tidak pernah terlihat dari lapisan aplikasi, padahal menentukan hasil program. Contoh itu juga menunjukkan bahwa angka tidak pernah tersimpan sebagai desimal, karena desimal hanya format tampilan, sedangkan yang tersimpan di dalam memori berupa bit.

Pola pembacaan yang berbeda atas satu nilai yang sama akan ditemui lagi pada modul Aritmetika, tempat komplemen dua dibahas secara lengkap. Untuk tahap ini, cukup dicatat bahwa setiap lapisan bekerja dengan bentuk yang paling nyaman baginya, lalu menyerahkan penerjemahan ke lapisan tetangganya. Kebiasaan membaca satu nilai dari beberapa lapisan sekaligus akan terus dipakai sepanjang jalur.

Kesalahan umum#

Kesalahan pertama berupa anggapan bahwa abstraksi bebas biaya. Anggapan itu lahir karena antarmuka tampak ringkas, padahal setiap panggilan lintas lapisan menambah pekerjaan saat program dijalankan. Biaya tersebut baru terasa ketika program diukur, misalnya saat versi yang keterbacaannya ditingkatkan ternyata berjalan beberapa kali lebih lambat. Perbaikannya berupa kebiasaan memperhatikan lapisan di bawah antarmuka ketika performa menjadi penting, misalnya memeriksa pola akses memori sebelum menyalahkan algoritmanya. Dengan kebiasaan itu, biaya abstraksi menjadi sesuatu yang diketahui dan dihitung, bukan kejutan yang baru muncul saat pengukuran.

Kesalahan kedua berupa pencarian “tempat angka sebenarnya berada”. Pencarian itu biasanya berawal dari anggapan bahwa tampilan desimal pada aplikasi adalah wujud asli bilangan. Fakta di dalam mesin berbeda, yaitu yang tersimpan berupa bit, sedangkan desimal, biner, dan heksadesimal sama-sama hanya format tampilan. Kesalahan semacam ini berbahaya justru karena programnya tetap berjalan tanpa pesan error apa pun. Perbaikannya berupa pengingat bahwa makna sebuah nilai ditetapkan oleh konvensi lapisan yang membacanya, sebagaimana ditunjukkan program di atas.

Ringkasan#

  • Lapisan abstraksi menyembunyikan implementasi lapisan di bawahnya dan menyediakan antarmuka tetap, sehingga lapisan di atas cukup memahami antarmuka tersebut.
  • Keuntungannya berupa kemudahan bernalar, portabilitas, dan pembagian kerja, sedangkan biayanya berupa pekerjaan terjemahan saat program berjalan dan rincian tersembunyi seperti perilaku cache serta representasi bilangan.
  • Pola bit yang sama dapat dibaca sebagai 202 atau -54, sehingga makna sebuah nilai ditetapkan oleh konvensi lapisan yang membacanya, bukan oleh bit itu sendiri.

Referensi#