-
Notifications
You must be signed in to change notification settings - Fork 36
Home
This Cheat Sheet contains all commands and code examples used in the Arm Research Starter Kit (RSK) on System Modeling using gem5
Follow these instructions to download all the required materials, build a gem5 binary and run simple examples in both System Call Emulation (SE) and Full System (FS) modes.
$ wget https://raw.githubusercontent.com/arm-university/arm-gem5-rsk/master/clone.sh
$ bash clone.sh
$ cd gem5
$ scons build/ARM/gem5.opt -j4 # parallel build
$ ./build/ARM/gem5.opt configs/example/arm/starter_se.py --cpu="minor" "tests/test-progs/hello/bin/arm/linux/hello" # Hello world!
$ ./build/ARM/gem5.opt configs/example/arm/starter_se.py --cpu="minor" --num-cores=2 "tests/test-progs/hello/bin/arm/linux/hello" "tests/test-progs/hello/bin/arm/linux/hello"
Get an Arm full system disk image from the gem5 downloads page, and set $M5_PATH
:
$ export M5_PATH="${PWD}/../m5_binaries"
$ mkdir -p "${M5_PATH}"
$ wget -P "${M5_PATH}" http://dist.gem5.org/dist/v22-0/arm/aarch-system-20220707.tar.bz2
$ tar -xjf "${M5_PATH}/aarch-system-20220707.tar.bz2" -C "${M5_PATH}"
$ wget -P "${M5_PATH}/disks" http://dist.gem5.org/dist/v22-0/arm/disks/ubuntu-18.04-arm64-docker.img.bz2
$ bunzip2 "${M5_PATH}/disks/ubuntu-18.04-arm64-docker.img.bz2"
$ echo "export M5_PATH=${M5_PATH}" >> ~/.bashrc
$ ./build/ARM/gem5.opt configs/example/arm/starter_fs.py --cpu="minor" --num-cores=1 \
--disk-image=$M5_PATH/disks/ubuntu-18.04-arm64-docker.img --root-device=/dev/vda1
$ telnet localhost 3456
$ m5 checkpoint
system.terminal: Listening for connections on port 3456
A more modern alternative is to use the m5term utility provided with gem5.
$ ./build/ARM/gem5.opt configs/example/arm/starter_fs.py --restore=m5out/cpt.TICKNUMBER/ --cpu="minor" --num-cores=1 --disk-image=$M5_PATH/disks/ubuntu-18.04-arm64-docker.img --root-device=/dev/vda1
We use the Stanford SingleSource workloads from the LLVM test-suite for benchmarking in the SE mode.
$ svn export https://github.com/llvm/llvm-test-suite/tags/llvmorg-3.9.0/SingleSource/Benchmarks/Stanford \
se-benchmarks
$ # Clone using Git
$ git clone https://github.com/llvm/llvm-test-suite.git se-benchmarks
$ cd se-benchmarks
$ git checkout -b llvmorg-3.9.0 tags/llvmorg-3.9.0
$ cd SingleSource/Benchmarks/Stanford
$
$ # Download an archive directly from GitHub
$ wget https://github.com/llvm/llvm-test-suite/archive/refs/tags/llvmorg-3.9.0.zip
$ unzip -qj llvmorg-3.9.0.zip llvm-test-suite-llvmorg-3.9.0/SingleSource/Benchmarks/Stanford/* -d se-benchmarks
$ cd se-benchmarks
$
$ sudo apt-get install gcc-aarch64-linux-gnu
SRCS = $(wildcard *.c)
PROGS = $(patsubst %.c,%,$(SRCS))
all: $(PROGS)
%: %.c
aarch64-linux-gnu-gcc --static $< -o $@
clean:
rm -f $(PROGS)
$ ./build/ARM/gem5.opt -d se_results/<benchmark> configs/example/arm/starter_se.py --cpu="hpi" /path_to_benchmark
$ ./build/ARM/gem5.opt -d se_results/Bubblesort configs/example/arm/starter_se.py --cpu="hpi" /path_to/se-benchmarks/Bubblesort
To compare the benchmarks, we first need to create a simple configuration file and specify a list of benchmarks to be compared, comparison parameters and an output file. Then, we just pass this configuration file to the read_results.sh
bash script.
Step1: create a .ini
under the se_results
directory (where the results of SE runs are stored), e.g. exe_time.ini
looks like this:
[Benchmarks]
Bubblesort
IntMM
Oscar
[Parameters]
simSeconds
[Output]
res_exe_time.txt
Step2: run the read_results.sh
bash script from the se_results
directory and pass the sample exe_time.ini
file as a parameter:
$ # After running simulations for `Bubblesort`, `IntMM`, and `Oscar`
$ cd se_results # where the results of SE runs are stored
$ bash ../../arm-gem5-rsk/read_results.sh exe_time.ini
$ cat res_exe_time.txt
We use The PARSEC Benchmark Suite for benchmarking in FS mode.
$ wget http://parsec.cs.princeton.edu/download/3.0/parsec-3.0.tar.gz
$ tar -xvzf parsec-3.0.tar.gz
We describe two ways to compile PARSEC benchmarks for Arm:
- Cross-compiling on an x86 machine
- Compiling on QEMU
The common steps apply to both approaches.
$ patch -p1 < ../arm-gem5-rsk/parsec_patches/static-patch.diff
$ mkdir tmp; cd tmp # make a tmp dir outside the parsec dir
$ wget -O config.guess 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD'
$ wget -O config.sub 'http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD'
$ cd /parsec_dir/ # cd to the parsec dir
$ find . -name "config.guess" -type f -print -execdir cp {} config.guess_old \;
$ find . -name "config.guess" -type f -print -execdir cp /absolute_path_to_tmp/config.guess {} \;
$ find . -name "config.sub" -type f -print -execdir cp {} config.sub_old \;
$ find . -name "config.sub" -type f -print -execdir cp /absolute_path_to_tmp/config.sub {} \;
$ wget https://releases.linaro.org/components/toolchain/binaries/latest-5/aarch64-linux-gnu/gcc-linaro-5.5.0-2017.10-x86_64_aarch64-linux-gnu.tar.xz
$ tar xvfJ gcc-linaro-5.5.0-2017.10-x86_64_aarch64-linux-gnu.tar.xz
$ patch -p1 < ../arm-gem5-rsk/parsec_patches/xcompile-patch.diff
$ export PARSECPLAT="aarch64-linux" # set the platform
$ source ./env.sh
$ parsecmgmt -a build -c gcc-hooks -p <pkgname>
$ patch -p1 < ../arm-gem5-rsk/parsec_patches/qemu-patch.diff
$ sudo apt-get install libglib2.0-dev libpixman-1-dev libfdt-dev libcap-dev libattr1-dev libcap-ng-dev ninja-build
$ git clone https://gitlab.com/qemu-project/qemu.git
$ cd qemu
$ ./configure --target-list=aarch64-softmmu --enable-virtfs --enable-slirp
$ make -j$(nproc)
$ wget http://releases.linaro.org/archive/15.06/openembedded/aarch64/Image
$ wget http://releases.linaro.org/archive/15.06/openembedded/aarch64/vexpress64-openembedded_lamp-armv8-gcc-4.9_20150620-722.img.gz
$ gzip -dc vexpress64-openembedded_lamp-armv8-gcc-4.9_20150620-722.img.gz > vexpress_arm64.img
$ ./qemu/build/aarch64-softmmu/qemu-system-aarch64 -m 1024 -cpu cortex-a53 -nographic -machine virt -kernel Image -append 'root=/dev/vda2 rw rootwait mem=1024M console=ttyAMA0,38400n8' -drive if=none,id=image,format=raw,file=vexpress_arm64.img -netdev user,id=user0 -device virtio-net-device,netdev=user0 -device virtio-blk-device,drive=image -fsdev local,id=r,path=/shared_directory/,security_model=none -device virtio-9p-device,fsdev=r,mount_tag=r
$ mount -t 9p -o trans=virtio r /mnt
$ cd /mnt # cd to the mounted PARSEC directory
$ source ./env.sh
$ parsecmgmt -a build -c gcc-hooks -p <pkgname>
$ poweroff # quit QEMU
To run PARSEC benchmarks on Arm, we need to enlarge the disk image and copy the directory of compiled benchmarks parsec-3.0
to it. Then, we need to generate benchmark runscripts and pass them via the --script
option to the simulation script starter_fs.py
.
$ cp ubuntu-18.04-arm64-docker.img expanded-ubuntu-18.04-arm64-docker.img
$ dd if=/dev/zero bs=1G count=20 >> ./expanded-ubuntu-18.04-arm64-docker.img # add 20G zeros
$ sudo parted expanded-ubuntu-18.04-arm64-docker.img resizepart 1 100% # grow partition 1
$ fdisk -l expanded-ubuntu-18.04-arm64-docker.img
Disk expanded-ubuntu-18.04-arm64-docker.img: 21.9 GiB, 23474836480 bytes, 45849290 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x93d4895b
Device Boot Start End Sectors Size Id Type
expanded-ubuntu-18.04-arm64-docker.img1 128 45849289 45849162 21.9G 83 Linux
In this example the start offset (in sectors) is 128 and the sector size (in bytes) is 512, giving a start offset of 128x512=65536 bytes.
$ mkdir disk_mnt
$ sudo mount -o loop,offset=65536 expanded-ubuntu-18.04-arm64-docker.img disk_mnt
$ df # find /dev/loopX for disk_mnt
$ sudo resize2fs /dev/loopX # resize filesystem
$ df # check that the Available space for disk_mnt is increased
$ sudo cp -r /path_to_compiled_parsec-3.0_dir/ disk_mnt/root # copy the compiled parsec-3.0 to the image
$ sudo ls disk_mnt/root # check the parsec-3.0 contents
$ sudo umount disk_mnt
We only show how to run PARSEC on the HPI model. Reading results from stats.txt
files can be done by using the read_results.sh
script, as shown for the SE mode.
$ cd arm-gem5-rsk/parsec_rcs
$ bash gen_rcs.sh -p <pkgname> -i <simsmall/simmedium/simlarge> -n <nth>
$ ./build/ARM/gem5.opt -d fs_results/<benchmark> configs/example/arm/starter_fs.py --cpu="hpi" --num-cores=1 --disk-image=$M5_PATH/disks/expanded-ubuntu-18.04-arm64-docker.img --root-device=/dev/vda1 --script=../arm-gem5-rsk/parsec_rcs/<benchmark>.rcS
# Example: canneal on 2 cores
$ ./build/ARM/gem5.opt -d fs_results/canneal_simsmall_2 configs/example/arm/starter_fs.py --cpu="hpi" --num-cores=2 --disk-image=$M5_PATH/disks/expanded-ubuntu-18.04-arm64-docker.img --root-device=/dev/vda1 --script=../arm-gem5-rsk/parsec_rcs/canneal_simsmall_2.rcS
Copyright © 2017 Arm Limited or its affiliates.
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License. Source code and configuration files are made available under the 3-clause BSD license, provided such license extends only to copyright in the software and shall not be construed as granting a license to any other intellectual property relating to a hardware implementation of the functionality of the software. The Arm name and Arm logo are registered trademarks or trademarks of Arm Limited (or its subsidiaries) in the US
For further information, visit: http://www.arm.com/company/policies/trademarks