Gem5: hello world
gem5 adalah simulator arsitektur komputer open-source yang dipakai untuk riset dan pembelajaran. Dengan gem5, sebuah komputer virtual (CPU, cache, bus, memori) dirakit lewat script Python, lalu sebuah program dijalankan di atasnya dan gem5 melaporkan statistik detail seperti jumlah cycle, jumlah instruksi, dan cache miss.
Catatan ini mencakup pemasangan gem5 sampai menjalankan program "Hello World" pertama.
Persiapan
Catatan ini memakai Linux (Ubuntu/Debian). Paket yang dibutuhkan (mengikuti dokumentasi gem5; cek dokumentasi resmi kalau versinya berbeda):
sudo apt install build-essential scons python3-dev git pre-commit \
zlib1g zlib1g-dev libprotobuf-dev protobuf-compiler libprotoc-dev \
libgoogle-perftools-dev libboost-all-dev libhdf5-serial-dev \
python3-pydot python3-venv python3-tk mypy m4 libcapstone-dev \
libpng-dev libelf-dev pkg-config wget cmake doxygen
Clone dan build
git clone https://github.com/gem5/gem5
cd gem5
scons build/ALL/gem5.opt -j <JUMLAH CPU>
Keterangan:
build/ALLartinya build mencakup semua ISA (x86, ARM, RISC-V, dan lainnya). Alternatifnyabuild/X86/gem5.optkalau hanya butuh x86, build-nya lebih ringan.gem5.optadalah varian dengan optimasi dan debug info secukupnya. Untuk debugging dengan gdb, pakaigem5.debug(lebih lambat, build lebih lama).-jmenentukan jumlah proses paralel. Isi dengan hasilnproc. Build pertama memakan waktu lama dan banyak RAM; kalau RAM kurang, kecilkan nilai-j.
Hello World pertama
gem5 menyertakan script contoh untuk menjalankan program sederhana:
build/ALL/gem5.opt configs/learning_gem5/part1/simple.py
Script ini merakit satu CPU sederhana dengan memori, lalu menjalankan program "Hello World" di dalamnya (mode Syscall Emulation). Kalau berhasil, di terminal muncul tulisan Hello world! dan baris penutup yang menyebut tick terakhir simulasi. Angka tick bisa berbeda antarversi gem5.
Isi folder m5out/
Setiap simulasi menghasilkan folder m5out/ di direktori tempat gem5 dijalankan:
| File | Isi |
|---|---|
stats.txt |
Semua statistik simulasi (cycle, instruksi, cache miss, dan lainnya) |
config.ini / config.json |
Konfigurasi sistem yang disimulasikan, lengkap dengan semua parameter |
config.dot.svg |
Diagram blok sistem |
Nilai yang pertama kali layak dilihat di stats.txt: simSeconds, simInsts, dan system.cpu.numCycles.
Merakit sistem sendiri
Script berikut melakukan hal yang sama dengan simple.py, tetapi ditulis manual agar terlihat tiap komponennya.
import m5
from m5.objects import *
from gem5.resources.resource import obtain_resource
system = System()
system.clk_domain = SrcClockDomain()
system.clk_domain.clock = "1GHz"
system.clk_domain.voltage_domain = VoltageDomain()
system.mem_mode = "timing"
system.mem_ranges = [AddrRange("512MB")]
system.cpu = X86TimingSimpleCPU()
system.membus = SystemXBar()
# Tanpa cache: CPU langsung ke membus
system.cpu.icache_port = system.membus.cpu_side_ports
system.cpu.dcache_port = system.membus.cpu_side_ports
# Khusus x86: interrupt controller disambung manual
system.cpu.createInterruptController()
system.cpu.interrupts[0].pio = system.membus.mem_side_ports
system.cpu.interrupts[0].int_requestor = system.membus.cpu_side_ports
system.cpu.interrupts[0].int_responder = system.membus.mem_side_ports
system.system_port = system.membus.cpu_side_ports
system.mem_ctrl = MemCtrl()
system.mem_ctrl.dram = DDR3_1600_8x8()
system.mem_ctrl.dram.range = system.mem_ranges[0]
system.mem_ctrl.port = system.membus.mem_side_ports
# Workload: program Hello World (SE mode)
binary = obtain_resource("x86-hello64-static").get_local_path()
system.workload = SEWorkload.init_compatible(binary)
process = Process()
process.cmd = [binary]
system.cpu.workload = process
system.cpu.createThreads()
root = Root(full_system=False, system=system)
m5.instantiate()
print("Beginning simulation!")
exit_event = m5.simulate()
print(f"Exiting @ tick {m5.curTick()} because {exit_event.getCause()}")
Jalankan dengan:
build/ALL/gem5.opt my_simple.py
Catatan: kalau resource x86-hello64-static tidak ditemukan di versi gem5 yang dipakai, ganti binary dengan path ke binary hello di source tree (tests/test-progs/hello/bin/x86/linux/hello).
Komponen yang dirakit
| Komponen | Fungsi |
|---|---|
System + clk_domain |
Kerangka sistem dan clock (1 GHz) |
mem_mode = "timing" |
Akses memori dimodelkan dengan latency |
X86TimingSimpleCPU |
Satu core x86 sederhana yang menunggu respons memori |
SystemXBar (membus) |
Bus penghubung. cpu_side_ports untuk pihak yang meminta data (CPU), mem_side_ports untuk pihak yang menyediakan data (memori, device)
|
interrupts[0] |
Interrupt controller x86, wajib disambung manual |
system_port |
Jalur khusus gem5 (misalnya untuk memuat binary ke memori sebelum simulasi) |
MemCtrl + DDR3_1600_8x8 |
Memory controller dan DRAM |
Tips: Makefile
Agar tidak mengetik path panjang berulang kali:
GEM5 ?= /home/haidhi/gem5/build/ALL/gem5.opt
SCRIPT ?= simple.py
OUTDIR ?= m5out
FLAGS ?= Exec
.PHONY: run stats debug clean
run:
$(GEM5) --outdir=$(OUTDIR) $(SCRIPT)
stats:
@grep -E "simSeconds|simInsts|numCycles|hostSeconds" $(OUTDIR)/stats.txt
debug:
$(GEM5) --debug-flags=$(FLAGS) --debug-file=debug.out --outdir=$(OUTDIR) $(SCRIPT)
clean:
rm -rf $(OUTDIR)
Baris perintah di Makefile harus diawali karakter tab, bukan spasi.
Masalah umum
No module named '_m5': script gem5 tidak bisa dijalankan denganpython3 script.py. Modul_m5ditanam di dalam binary, jadi script harus dijalankan lewatgem5.opt.- Garis bawah merah di VSCode untuk
System,SrcClockDomain, dll: modulm5.objectsdibangkitkan saat build dan source-nya di-embed ke binary, sehingga IDE tidak menemukannya. Script tetap berjalan normal. Garis bawahnya bisa dimatikan lewat settingpython.analysis.diagnosticSeverityOverridesatau komentar# pyright: reportUndefinedVariable=falsedi baris atas script. - Build gagal karena kehabisan memori: kecilkan nilai
-j.