Jelajahi gagasan arsitektur John Hennessy: mengapa performa tak lagi tumbuh “gratis”, bagaimana paralelisme membantu, dan tradeoff yang membentuk sistem modern.

John Hennessy adalah salah satu arsitek yang paling jelas menjelaskan mengapa komputer menjadi lebih cepat—dan mengapa kemajuan itu kadang-kadang terhenti. Selain merancang prosesor berpengaruh dan membantu mempopulerkan gagasan RISC, ia membantu memberi pembuat sistem kosakata praktis untuk keputusan performa: apa yang harus dioptimalkan, apa yang tidak, dan bagaimana membedakannya.
Ketika orang berbicara tentang “skalabilitas performa,” mereka sering bermaksud “program saya berjalan lebih cepat.” Dalam sistem nyata, skala adalah negosiasi tiga arah antara kecepatan, biaya, dan daya/energi. Perubahan yang membuat satu beban kerja 20% lebih cepat mungkin juga membuat chip lebih mahal, server lebih sulit didinginkan, atau baterai lebih cepat habis. Kerangka berpikir Hennessy penting karena memperlakukan batasan-batasan itu sebagai masukan rekayasa normal—bukan kejutan yang tidak menyenangkan.
Pertama adalah paralelisme: melakukan lebih banyak pekerjaan secara bersamaan. Ini muncul di dalam inti (trik tingkat instruksi), antar inti (thread), dan di seluruh mesin.
Kedua adalah spesialisasi: menggunakan alat yang tepat untuk tugasnya. GPU, encoder video, dan akselerator ML ada karena CPU umum tidak bisa melakukan semuanya secara efisien.
Ketiga adalah tradeoff: setiap “kemenangan” punya harga. Kunci adalah memahami di mana batasnya—komputasi, memori, komunikasi, atau energi.
Ini bukan biografi mendalam. Sebaliknya, ini adalah kumpulan konsep praktis yang bisa Anda terapkan saat membaca benchmark, memilih perangkat keras, atau merancang perangkat lunak yang perlu tumbuh dengan permintaan.
Untuk waktu yang lama dalam sejarah komputasi, peningkatan performa terasa hampir otomatis. Saat transistor menjadi lebih kecil, pembuat chip bisa menempatkan lebih banyak transistor pada prosesor dan sering menjalankannya pada frekuensi yang lebih tinggi. Tim perangkat lunak bisa menjalankan program yang sama pada mesin baru dan melihatnya selesai lebih cepat—tanpa perlu merombak.
Ini adalah periode ketika generasi CPU baru sering berarti GHz lebih tinggi, biaya per transistor lebih rendah, dan percepatan yang nyata untuk kode sehari-hari. Sebagian besar keuntungan itu tidak mengharuskan pengembang berpikir berbeda; compiler dan peningkatan perangkat keras melakukan pekerjaan berat.
Akhirnya, peningkatan frekuensi berhenti menjadi kemenangan sederhana karena daya dan panas meningkat terlalu cepat. Memperkecil transistor tidak otomatis menurunkan daya sebagaimana sebelumnya, dan mendorong frekuensi lebih tinggi membuat chip lebih panas. Pada titik tertentu, faktor pembatas bukan lagi “Bisakah kita membuatnya lebih cepat?” tetapi “Bisakah kita mendinginkannya dan memberinya daya secara andal?”
Bayangkan mesin mobil. Anda sering bisa berjalan lebih cepat dengan menaikkan putaran—sampai Anda mencapai batas: konsumsi bahan bakar melonjak, bagian terlalu panas, dan sistem menjadi tidak aman. CPU menghadapi batas serupa: menaikkan “RPM” (kecepatan jam) menghabiskan energi secara tidak proporsional dan menghasilkan panas lebih banyak daripada yang bisa ditangani sistem.
Saat penskalaan frekuensi melambat, performa menjadi sesuatu yang harus Anda peroleh lewat desain: lebih banyak kerja paralel, pemanfaatan cache dan memori yang lebih baik, perangkat keras khusus, dan pilihan perangkat lunak yang hati-hati. Pesan Hennessy cocok dengan pergeseran ini: keuntungan besar sekarang datang dari membuat seluruh sistem—perangkat keras dan perangkat lunak—bekerja bersama, bukan berharap chip berikutnya menyelamatkan Anda secara otomatis.
Instruction-Level Parallelism (ILP) adalah ide melakukan langkah-langkah kecil sekaligus di dalam satu inti CPU. Bahkan jika program Anda “single-threaded,” prosesor sering dapat menumpangkan pekerjaan: sementara satu instruksi menunggu sesuatu, instruksi lain bisa mulai—jika mereka tidak saling bergantung.
Cara sederhana membayangkan ILP adalah pipelining. Bayangkan jalur perakitan: satu tahap mengambil instruksi, tahap lain mendekode, tahap lain mengeksekusi, dan tahap lain menulis hasil. Setelah pipeline penuh, CPU dapat menyelesaikan kira-kira satu instruksi per siklus, meskipun setiap instruksi tetap membutuhkan beberapa tahap untuk melewatinya.
Pipelining membantu performa bertahun-tahun karena meningkatkan throughput tanpa mengharuskan programmer menulis ulang semuanya.
Program nyata tidak berjalan lurus. Mereka bertemu cabangan ("if ini, maka itu"), dan CPU harus memutuskan apa yang akan diambil berikutnya. Jika menunggu untuk mengetahuinya, pipeline bisa macet.
Branch prediction adalah cara CPU menebak jalur berikutnya agar pekerjaan terus mengalir. Saat tebakan benar, performa tetap tinggi. Saat salah, CPU membuang pekerjaan jalur yang salah dan membayar penalti—siklus terbuang dan energi terbuang.
Mendorong ILP lebih jauh membutuhkan perangkat keras tambahan untuk menemukan instruksi independen, menyusunnya kembali dengan aman, dan pulih dari kesalahan seperti tebakan cabang yang salah. Itu menambah kompleksitas dan upaya validasi, meningkatkan penggunaan daya, dan sering memberikan keuntungan yang semakin kecil setiap generasi.
Ini salah satu pelajaran berulang Hennessy: ILP bernilai, tetapi mencapai batas praktis—jadi penskalaan performa berkelanjutan akhirnya membutuhkan tuas lain, bukan hanya “eksekusi single-core yang makin cerdik.”
Hukum Amdahl mengingatkan bahwa mempercepat sebagian pekerjaan tidak bisa mempercepat seluruh pekerjaan melampaui apa yang diizinkan oleh bagian serial yang tersisa. Anda tidak perlu matematika berat untuk menggunakannya—Anda hanya perlu memperhatikan apa yang tidak dapat diparalelkan.
Bayangkan toko grosir dengan satu pelanggan dan proses kasir:
Jika pembayaran selalu memakan, katakanlah, 10% dari total waktu, maka bahkan jika Anda membuat pemindaian "instan" dengan menambah kasir, Anda tidak bisa mendapatkan lebih dari kira-kira 10× percepatan keseluruhan. Bagian serial menjadi plafon.
Memasak menunjukkan pola yang sama: Anda bisa mencincang sayuran sementara air memanas (paralel), tetapi Anda tidak bisa “memparalelkan” memanggang kue yang harus berada di dalam oven selama 30 menit.
Inti wawasan adalah bahwa beberapa persen terakhir pekerjaan serial yang tersisa membatasi semuanya. Program yang “99% paralel” terdengar luar biasa—sampai Anda mencoba menskalakannya ke banyak core dan menemukan bahwa 1% bagian serial menjadi kendala panjang.
Hukum Amdahl adalah alasan mengapa “cukup tambahkan core” sering mengecewakan. Lebih banyak core membantu hanya ketika ada cukup pekerjaan paralel dan hambatan serial (sinkronisasi, I/O, fase single-thread, stall memori) dijaga agar kecil.
Ini juga menjelaskan mengapa akselerator bisa rumit: jika GPU mempercepat satu kernel, tetapi sisa pipeline tetap serial, keuntungan keseluruhan bisa saja terbatas.
Sebelum berinvestasi dalam paralelisme, tanyakan: Berapa fraksi yang benar-benar paralel, dan apa yang tetap serial? Kemudian habiskan usaha di tempat waktu benar-benar dihabiskan—seringkali jalur serial yang “membosankan”—karena itu yang menentukan batas.
Selama bertahun-tahun, peningkatan performa biasanya berarti membuat satu inti CPU berjalan lebih cepat. Pendekatan itu mencapai batas praktis: frekuensi lebih tinggi meningkatkan panas dan daya, dan pipeline yang lebih dalam tidak selalu diterjemahkan menjadi percepatan dunia nyata yang proporsional. Jawaban mainstream adalah menaruh banyak core pada satu chip dan meningkatkan performa dengan melakukan lebih banyak pekerjaan sekaligus.
Multicore membantu dalam dua cara berbeda:
Perbedaan ini penting dalam perencanaan: server mungkin langsung mendapat manfaat dari menangani lebih banyak permintaan secara bersamaan, sementara aplikasi desktop mungkin hanya terasa lebih cepat jika pekerjaan itu sendiri dapat diparalelkan.
Paralelisme tingkat thread tidak terjadi otomatis. Perangkat lunak perlu mengekspos pekerjaan paralel menggunakan thread, antrean tugas, atau kerangka kerja yang memecah pekerjaan menjadi unit-unit independen. Tujuannya adalah menjaga core tetap sibuk tanpa terus menunggu satu sama lain.
Langkah praktis umum termasuk memparalelkan loop, memisahkan tahap independen (mis. decode → process → encode), atau menangani banyak permintaan/event secara bersamaan.
Penskalaan multicore sering terhenti pada overhead:
Pesan lebih luas Hennessy berlaku di sini: paralelisme kuat, tetapi percepatan nyata tergantung pada desain sistem yang cermat dan pengukuran jujur—bukan sekadar menambah core.
CPU hanya bisa bekerja pada data yang sudah tersedia. Ketika data belum siap—karena masih datang dari memori—CPU harus menunggu. Waktu tunggu ini adalah latensi memori, dan itu bisa mengubah prosesor “cepat” menjadi mesin mahal yang menganggur.
Pikirkan memori seperti gudang di seberang kota. Bahkan jika pekerja Anda (core CPU) sangat cepat, mereka tidak bisa merakit apa pun jika komponennya terjebak macet. Prosesor modern dapat mengeksekusi miliar operasi per detik, tetapi perjalanan ke memori utama bisa memakan ratusan siklus CPU. Celah-celah itu terakumulasi.
Untuk mengurangi waktu tunggu, komputer menggunakan cache, area memori kecil dan cepat yang lebih dekat ke CPU—seperti rak terdekat yang diisi dengan komponen yang paling sering digunakan. Ketika data yang dibutuhkan sudah ada di rak ("cache hit"), kerja berlanjut lancar. Saat tidak ada ("miss"), CPU harus mengambil dari lebih jauh, membayar biaya latensi penuh.
Latensi adalah “berapa lama sampai item pertama tiba.” Bandwidth adalah “berapa banyak item yang bisa tiba per detik.” Anda bisa punya bandwidth tinggi (jalan raya lebar) tetapi tetap menderita latensi tinggi (jarak jauh). Beberapa beban kerja streaming banyak data (terbatas bandwidth), sementara yang lain sering membutuhkan potongan kecil yang tersebar (terbatas latensi). Sistem bisa terasa lambat dalam kedua kasus.
Poin luas Hennessy tentang batas muncul di sini sebagai memory wall: kecepatan CPU meningkat lebih cepat daripada waktu akses memori selama bertahun-tahun, sehingga prosesor semakin banyak menghabiskan waktu menunggu. Itulah mengapa peningkatan performa sering datang dari memperbaiki lokalitas data (agar cache lebih membantu), memikirkan ulang algoritma, atau mengubah keseimbangan sistem—bukan hanya membuat inti CPU lebih cepat.
Lama waktu, “lebih cepat” biasanya berarti "menaikkan jam." Pola pikir itu runtuh saat Anda memperlakukan daya sebagai anggaran keras, bukan urusan belakangan. Setiap watt tambahan berubah menjadi panas yang harus dibuang, baterai yang terkuras, atau listrik yang harus dibayar. Performa tetap tujuan—tetapi performa per watt-lah yang menentukan apa yang bisa dikapalkan dan diskalakan.
Daya bukan sekadar detail teknis; itu adalah kendala produk. Laptop yang bagus di benchmark tapi menahan diri setelah dua menit terasa lambat. Ponsel yang merender halaman instan tapi kehilangan 20% baterai melakukan pekerjaan buruk. Bahkan di server, Anda mungkin punya kapasitas komputasi cadangan tetapi tidak punya daya atau kapasitas pendinginan.
Menaikkan frekuensi sangat mahal karena daya meningkat tajam saat Anda mendorong tegangan dan aktivitas switching. Secara sederhana, daya dinamis mengikuti pola:
Jadi 10–20% terakhir dari kecepatan jam bisa menuntut lonjakan watt yang jauh lebih besar—mengakibatkan batas termal dan throttling daripada peningkatan berkelanjutan.
Inilah mengapa desain modern menekankan efisiensi: penggunaan paralelisme yang lebih luas, manajemen daya yang lebih cerdas, dan jam "cukup baik" dipasangkan dengan mikroarsitektur yang lebih baik. Di pusat data, daya adalah pos pengeluaran yang bersaing dengan biaya perangkat keras dalam jangka panjang. Di cloud, kode yang tidak efisien bisa langsung menaikkan tagihan—karena Anda membayar waktu, core, dan (seringkali secara tidak langsung) energi melalui harga.
Pesan berulang Hennessy sederhana: penskalaan performa bukan hanya masalah perangkat keras atau perangkat lunak. Co-design perangkat keras–perangkat lunak berarti menyelaraskan fitur CPU, compiler, runtime, dan algoritma di sekitar beban kerja nyata—agar sistem menjadi lebih cepat dalam menjalankan apa yang sebenarnya Anda pakai, bukan hanya yang terlihat bagus di lembar spesifikasi.
Contoh klasik adalah dukungan compiler yang membuka kemampuan perangkat keras. Prosesor mungkin memiliki unit vektor lebar (SIMD), prediksi cabang, atau instruksi yang menggabungkan operasi, tetapi perangkat lunak harus disusun supaya compiler dapat menggunakannya dengan aman.
Jika hambatannya adalah stall memori, kontensi kunci, atau I/O, jam yang lebih tinggi atau lebih banyak core mungkin hanya memindahkan jarum sedikit. Sistem hanya mencapai batas yang sama lebih cepat. Tanpa perubahan perangkat lunak—struktur paralel yang lebih baik, lebih sedikit cache miss, lebih sedikit sinkronisasi—perangkat keras baru bisa tetap menganggur.
Saat mempertimbangkan optimasi atau platform baru, tanyakan:
RISC (Reduced Instruction Set Computing) bukan sekadar slogan tetapi taruhan strategis: jika Anda menjaga set instruksi kecil dan teratur, Anda dapat membuat setiap instruksi dieksekusi cepat dan dapat diprediksi. John Hennessy ikut mempopulerkan pendekatan ini dengan menekankan bahwa performa sering meningkat ketika tugas perangkat keras lebih sederhana, meskipun perangkat lunak menggunakan lebih banyak instruksi secara keseluruhan.
Set instruksi yang ramping cenderung memiliki format konsisten dan operasi yang mudah (load, store, add, branch). Keteraturan itu memudahkan CPU untuk:
Intinya, saat instruksi mudah ditangani, prosesor bisa menghabiskan lebih banyak waktu untuk kerja berguna dan lebih sedikit waktu mengelola pengecualian dan kasus khusus.
Instruksi kompleks bisa mengurangi jumlah instruksi yang dibutuhkan program, tetapi sering meningkatkan kompleksitas perangkat keras—lebih banyak sirkuit, lebih banyak kasus tepi, lebih banyak daya yang dihabiskan pada logika kontrol. RISC membalik ini: gunakan blok bangunan yang lebih sederhana, lalu andalkan compiler dan mikroarsitektur untuk mengekstrak kecepatan.
Itu dapat diterjemahkan menjadi efisiensi energi yang lebih baik juga. Desain yang membuang lebih sedikit siklus pada overhead dan kontrol sering membuang lebih sedikit joule, yang menjadi penting saat daya dan panas membatasi seberapa cepat chip bisa berjalan.
CPU modern—baik di ponsel, laptop, atau server—meminjam banyak prinsip gaya RISC: pipeline eksekusi yang teratur, banyak optimasi di sekitar operasi sederhana, dan ketergantungan kuat pada compiler. Sistem berbasis ARM adalah contoh nyata garis keturunan RISC yang mencapai komputasi umum, tetapi pelajaran utamanya bukan "merek mana menang."
Prinsip yang bertahan adalah: pilih kesederhanaan ketika itu memungkinkan throughput lebih tinggi, efisiensi yang lebih baik, dan skala ide inti.
Spesialisasi berarti menggunakan perangkat keras yang dirancang untuk melakukan satu kelas pekerjaan sangat baik, daripada meminta CPU umum melakukan segalanya. Contoh umum meliputi GPU untuk grafis dan matematik paralel, akselerator AI (NPU/TPU) untuk operasi matriks, dan blok fungsi tetap seperti codec video untuk H.264/HEVC/AV1.
CPU dirancang untuk fleksibilitas: banyak instruksi, banyak logika kontrol, dan penanganan cepat untuk kode yang bercabang. Akselerator menukar fleksibilitas itu demi efisiensi. Mereka mengalokasikan lebih banyak anggaran chip ke operasi yang benar-benar dibutuhkan (mis. multiply–accumulate), meminimalkan overhead kontrol, dan sering menggunakan presisi lebih rendah (seperti INT8 atau FP16) bila akurasi mengizinkan.
Fokus itu berarti lebih banyak kerja per watt: lebih sedikit instruksi, lebih sedikit perpindahan data, dan lebih banyak eksekusi paralel. Untuk beban kerja yang didominasi oleh kernel berulang—rendering, inference, encoding—ini bisa menghasilkan percepatan dramatis sambil menjaga daya terkendali.
Spesialisasi punya biaya. Anda bisa kehilangan fleksibilitas (perangkat keras hebat untuk satu tugas dan biasa saja untuk lainnya), membayar biaya engineering dan validasi yang lebih tinggi, dan bergantung pada ekosistem perangkat lunak—driver, compiler, pustaka—yang bisa tertinggal atau mengunci Anda ke vendor.
Pilih akselerator ketika:
Tetap gunakan CPU ketika beban kerja tidak teratur, berubah cepat, atau biaya perangkat lunak lebih besar daripada penghematannya.
Setiap “kemenangan” performa dalam arsitektur komputer punya tagihan yang melekat. Karya Hennessy berulang pada kebenaran praktis: mengoptimalkan sistem berarti memilih apa yang Anda rela korbankan.
Beberapa ketegangan muncul berulang:
Latensi vs. throughput: Anda dapat membuat satu permintaan selesai lebih cepat (latensi lebih rendah), atau menyelesaikan lebih banyak permintaan per detik (throughput lebih tinggi). CPU yang di-tune untuk tugas interaktif mungkin terasa lebih responsif, sementara desain untuk batch processing mungkin mengejar total pekerjaan selesai.
Kesederhanaan vs. fitur: Desain sederhana sering lebih mudah dioptimalkan, diverifikasi, dan diskalakan. Desain kaya fitur bisa membantu beban kerja tertentu, tetapi menambah kompleksitas yang dapat memperlambat kasus umum.
Biaya vs. kecepatan: Perangkat keras yang lebih cepat umumnya lebih mahal—lebih banyak area silikon, lebih banyak bandwidth memori, lebih banyak pendinginan, lebih banyak waktu engineering. Kadang solusi “termurah” untuk percepatan adalah mengubah perangkat lunak atau beban kerja.
Mudah mengoptimalkan untuk satu angka dan tanpa sengaja merusak pengalaman pengguna nyata.
Misalnya, menaikkan frekuensi dapat meningkatkan daya dan panas, memaksa throttling yang merusak performa berkelanjutan. Menambahkan core dapat meningkatkan throughput paralel, tetapi bisa menambah kontensi untuk memori, membuat setiap core kurang efektif. Cache lebih besar dapat mengurangi miss (baik untuk latensi) tetapi menambah area chip dan energi per akses (buruk untuk biaya dan efisiensi).
Perspektif Hennessy pragmatis: definisikan beban kerja yang Anda pedulikan, lalu optimalkan untuk realitas itu.
Server yang menangani jutaan permintaan serupa peduli tentang throughput yang dapat diprediksi dan energi per operasi. Laptop peduli tentang responsivitas dan daya tahan baterai. Pipeline data mungkin menerima latensi lebih tinggi jika total waktu pekerjaan membaik. Benchmark dan spesifikasi headline berguna, tetapi hanya jika sesuai dengan kasus penggunaan nyata Anda.
Pertimbangkan menambahkan tabel kecil dengan kolom seperti: Keputusan, Membantu, Merugikan, Terbaik untuk. Baris bisa meliputi “lebih banyak core,” “cache lebih besar,” “frekuensi lebih tinggi,” “unit vektor lebih lebar,” dan “memori lebih cepat.” Ini membuat tradeoff konkret—dan menjaga diskusi terikat pada hasil, bukan hype.
Klaim performa hanya sebaik pengukuran di baliknya. Benchmark bisa benar secara teknis namun menyesatkan jika tidak menyerupai beban kerja nyata Anda: ukuran data berbeda, perilaku cache berbeda, pola I/O berbeda, konkurensi berbeda, atau bahkan campuran baca vs tulis yang berbeda dapat membalik hasil. Itulah mengapa arsitek dalam tradisi Hennessy memperlakukan benchmarking sebagai eksperimen, bukan trofi.
Throughput adalah berapa banyak pekerjaan yang Anda selesaikan per unit waktu (requests/second, jobs/hour). Cocok untuk perencanaan kapasitas, tetapi pengguna tidak merasakan rata-rata.
Tail latency fokus pada permintaan paling lambat—sering dilaporkan sebagai p95/p99. Sistem bisa memiliki rata-rata latensi baik sementara p99 buruk karena antrean, GC pauses, kontensi kunci, atau tetangga berisik.
Utilization adalah seberapa "sibuk" sumber daya (CPU, bandwidth memori, disk, jaringan). Utilization tinggi bisa bagus—sampai mendorong Anda ke antrean panjang di mana tail latency melonjak.
Gunakan loop yang dapat diulang:
Catat konfigurasi, versi, dan lingkungan agar hasil bisa direproduksi.
Jangan memilih "run terbaik", dataset yang paling ramah, atau satu metrik yang mempercantik perubahan Anda. Dan jangan terlalu menggeneralisir: kemenangan pada satu mesin atau suite benchmark mungkin tidak berlaku untuk deployment Anda, kendala biaya Anda, atau trafik jam sibuk pengguna Anda.
Pesan abadi Hennessy praktis: performa tidak menskala karena berharap—ia menskala ketika Anda memilih jenis paralelisme yang tepat, menghormati batas energi, dan mengoptimalkan untuk beban kerja yang benar-benar penting.
Paralelisme adalah jalur utama ke depan, tetapi itu tidak pernah "gratis." Baik Anda mengejar ILP, throughput multicore, atau akselerator, keuntungan mudah habis dan overhead koordinasi tumbuh.
Efisiensi adalah fitur. Energi, panas, dan perpindahan memori sering membatasi kecepatan dunia nyata jauh sebelum angka GHz puncak. Desain lebih cepat yang tidak bisa beroperasi dalam batas daya atau memori tidak akan memberikan kemenangan yang terlihat pengguna.
Fokus beban kerja mengalahkan optimasi generik. Hukum Amdahl mengingatkan untuk menghabiskan usaha di tempat waktu dihabiskan. Profil dulu; optimalkan setelahnya.
Ide-ide ini bukan hanya untuk perancang CPU. Jika Anda membangun aplikasi, constraint yang sama muncul sebagai antrean, tail latency, tekanan memori, dan biaya cloud. Satu cara praktis mengoperasionalkan "co-design" adalah menjaga keputusan arsitektur dekat dengan umpan balik beban kerja: ukur, iterasi, dan rilis.
Untuk tim yang menggunakan alur kerja build berbasis chat seperti Koder.ai, ini bisa sangat berguna: Anda dapat membuat prototipe layanan atau UI dengan cepat, lalu menggunakan profiling dan benchmark untuk memutuskan apakah akan mengejar paralelisme (mis. konkurensi permintaan), memperbaiki lokalitas data (mis. lebih sedikit round-trip, query yang lebih ketat), atau memperkenalkan spesialisasi (mis. memindahkan tugas berat). Fitur platform seperti mode perencanaan, snapshot, dan rollback memudahkan pengujian perubahan yang mempengaruhi performa secara bertahap—tanpa menjadikan optimisasi sebagai jalan satu arah.
Jika Anda ingin lebih banyak posting seperti ini, jelajahi /blog.