Skip to content

Commit 7440762

Browse files
committed
Improved benchmarking for WAMR, LLVM 20
1 parent ae199e5 commit 7440762

21 files changed

+64
-1482
lines changed

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ ziskemu -e build/bin/println.zkvm.elf
8585
```
8686

8787
#### QEMU RISC-V
88+
8889
```bash
8990
./platform/riscv-qemu/scripts/c2riscv-qemu.sh \
9091
build/c-packages/println \
@@ -96,14 +97,18 @@ qemu-system-riscv64 -machine virt -bios none \
9697
```
9798

9899
#### QEMU RISC-V WAMR
100+
101+
Include OpenSBI BIOS (`-bios default` instead of `-bios none`) such that a shutdown function is present for improved benchmarking.
102+
99103
```bash
100104
./platform/riscv-wamr-qemu/scripts/wasm2wamr-qemu.sh \
101105
examples/build-wasm/go/fibonacci.wasm \
102106
build/bin/fibonacci.wamr.elf
103107

104108
# Run in QEMU
105-
qemu-system-riscv64 -machine virt -m 1024M -bios none \
106-
-kernel build/bin/fibonacci.wamr.elf -nographic
109+
./docker/docker-shell.sh qemu-system-riscv64 -machine virt -m 1024M \
110+
-kernel build/bin/fibonacci.wamr.elf -nographic -icount shift=0 \
111+
-plugin /libinsn.so
107112
```
108113

109114
## Examples

docker/Dockerfile

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,16 @@ RUN git clone https://github.com/turbolent/w2c2.git /opt/w2c2 && \
5656

5757
RUN apt update && apt install -y git build-essential ninja-build pkg-config libglib2.0-dev libpixman-1-dev
5858

59+
# Include patch for insn.c because otherwise this error appears due to unknown
60+
# instructions:
61+
#
62+
# ERROR:../tests/tcg/plugins/insn.c:97:vcpu_init: assertion failed: (count > 0)
63+
#
64+
# https://lists.gnu.org/archive/html/qemu-discuss/2025-08/msg00001.html
5965
RUN git clone https://git.qemu.org/git/qemu.git && \
6066
cd qemu && \
61-
./configure --target-list=riscv64-linux-user --enable-plugins && \
67+
sed -i 's/g_assert(count > 0)/g_assert(count >= 0)/g' tests/tcg/plugins/insn.c && \
68+
./configure --target-list=riscv64-linux-user,riscv64-softmmu --enable-plugins && \
6269
make -j4 && \
6370
make install && \
6471
cp build/tests/tcg/plugins/libinsn.so /libinsn.so && \
@@ -74,20 +81,16 @@ RUN git clone https://git.qemu.org/git/qemu.git && \
7481
# https://github.com/bytecodealliance/wasm-micro-runtime/issues/418
7582
# https://github.com/bytecodealliance/wasm-micro-runtime/issues/531
7683
#
77-
# Additionally use LLVM 19. Profiling wamrc when compiling a large wasm
78-
# file like stateful.wasm shows that AttemptToFoldSymbolOffsetDifference
84+
# Additionally use LLVM 20. Profiling wamrc when compiling a large wasm
85+
# file like stateless.wasm shows that AttemptToFoldSymbolOffsetDifference
7986
# consumes most of the compile time. LLVM 19 contains a fix for this
80-
# though
87+
# though. Also large code model is in principle supported for RISC-V
88+
# since version 20.
8189
#
8290
# https://github.com/llvm/llvm-project/issues/81440
83-
RUN git clone https://github.com/bytecodealliance/wasm-micro-runtime.git /opt/wamr
84-
COPY platform/riscv-wamr-qemu/wamr-platform/ /opt/wamr/core/shared/platform/zkvm/
85-
RUN cd /opt/wamr && \
86-
sed -i "s/find_package(Threads REQUIRED)/find_package(Threads)/g" CMakeLists.txt && \
87-
sed -i "/SymbolMap target_sym_map/a REG_SYM(__floatundisf)," core/iwasm/aot/arch/aot_reloc_riscv.c && \
88-
sed -i "/SymbolMap target_sym_map/a REG_SYM(__floatdisf)," core/iwasm/aot/arch/aot_reloc_riscv.c && \
89-
sed -i "/SymbolMap target_sym_map/a REG_SYM(__ltsf2)," core/iwasm/aot/arch/aot_reloc_riscv.c && \
90-
sed -i "s/18\.x/19.x/g" build-scripts/build_llvm.py && \
91+
RUN git clone https://github.com/psilva261/wasm-micro-runtime-zkvm.git /opt/wamr/ && \
92+
cd /opt/wamr && \
93+
git checkout zkvm && \
9194
cmake . \
9295
-DWAMR_BUILD_PLATFORM=zkvm \
9396
-DWAMR_BUILD_TARGET=AOT \

platform/riscv-qemu/scripts/c2riscv-qemu.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ PREFIX=/opt/riscv-newlib/bin/riscv64-unknown-elf-
6969

7070
# Compiler flags (using -O0 for faster compilation of large generated files)
7171
CFLAGS=(
72-
-march=rv64ima
72+
-march=rv64ima_zicsr
7373
-mabi=lp64
7474
-mcmodel=medany
7575
-specs=nosys.specs

platform/riscv-wamr-qemu/main.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,12 @@
66
extern const char wasmModuleBuffer[];
77
extern int wasmModuleBuffer_length;
88

9+
static inline unsigned long rdinstret(void) {
10+
unsigned long v;
11+
asm volatile ("csrr %0, instret" : "=r"(v));
12+
return v;
13+
}
14+
915
int main(void) {
1016
int argc = 0;
1117
char *argv[0];
@@ -17,6 +23,10 @@ int main(void) {
1723
wasm_function_inst_t func;
1824
wasm_exec_env_t exec_env;
1925
uint32 size, stack_size = 16*1024*1024;
26+
unsigned long instrs_start, instrs_init, instrs_load, instrs_inst,
27+
instrs_exec, instrs_unload, instrs_end;
28+
29+
instrs_start = rdinstret();
2030

2131
wasm_runtime_set_log_level(WASM_LOG_LEVEL_VERBOSE);
2232

@@ -25,28 +35,40 @@ int main(void) {
2535
printf("runtime init failed\n");
2636
exit(1);
2737
}
38+
instrs_init = rdinstret();
2839

2940
/* parse the WASM file from buffer and create a WASM module */
3041
module = wasm_runtime_load(wasmModuleBuffer, wasmModuleBuffer_length, error_buf, sizeof(error_buf));
3142
if (module == 0) {
3243
printf("runtime load module failed: %s\n", error_buf);
3344
exit(1);
3445
}
46+
instrs_load = rdinstret();
3547

3648
/* create an instance of the WASM module (WASM linear memory is ready) */
3749
module_inst = wasm_runtime_instantiate(module, stack_size, 0, error_buf, sizeof(error_buf));
3850
if (module_inst == 0) {
3951
printf("wasm_runtime_instantiate failed as module_inst=%p: %s\n", module_inst, error_buf);
4052
exit(1);
4153
}
54+
instrs_inst = rdinstret();
4255

4356
if (!wasm_application_execute_main(module_inst, argc, argv)) {
4457
printf("error executing main\n");
4558
printf("exception: %s\n", wasm_runtime_get_exception(module_inst));
4659
}
60+
instrs_exec = rdinstret();
4761

4862
printf("wasm_runtime_unload...\n");
4963
wasm_runtime_unload(module);
64+
instrs_end = instrs_unload = rdinstret();
65+
66+
printf("instructions runtime init: %lu\n", instrs_init-instrs_start);
67+
printf("instructions runtime load: %lu\n", instrs_load-instrs_init);
68+
printf("instructions runtime instantiate: %lu\n", instrs_inst-instrs_load);
69+
printf("instructions runtime exec: %lu\n", instrs_exec-instrs_inst);
70+
printf("instructions runtime unload: %lu\n", instrs_unload-instrs_exec);
71+
printf("instructions in total: %lu\n", instrs_end-instrs_start);
5072

5173
return 0;
5274
}

platform/riscv-wamr-qemu/scripts/wasm2wamr-qemu.sh

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ if [ $# -lt 2 ]; then
2828
echo " $0 build/.c-packages/println build/bin/println.riscv.elf"
2929
echo ""
3030
echo "To run in QEMU:"
31-
echo " qemu-system-riscv64 -machine virt -bios none \\"
31+
echo " ./docker/docker-shell.sh qemu-system-riscv64 -machine virt \\"
32+
echo " -m 1024M -icount shift=0 -plugin /libinsn.so \\"
3233
echo " -kernel build/bin/println.riscv.elf -nographic \\"
3334
echo " -semihosting-config enable=on,target=native"
3435
echo ""
@@ -113,7 +114,7 @@ PREFIX=/opt/riscv-newlib/bin/riscv64-unknown-elf-
113114

114115
# Compiler flags (using -O0 for faster compilation of large generated files)
115116
CFLAGS=(
116-
-march=rv64ima
117+
-march=rv64ima_zicsr
117118
-mabi=lp64
118119
-mcmodel=medany
119120
-specs=nosys.specs
@@ -185,8 +186,9 @@ if [ $? -eq 0 ] && [ -f "$OUTPUT" ]; then
185186
echo "Size: $SIZE"
186187
echo ""
187188
echo "To run in QEMU:"
188-
echo " qemu-system-riscv64 -machine virt -m 1024M \\"
189-
echo " -bios none -kernel $OUTPUT -nographic \\"
189+
echo " ./docker/docker-shell.sh qemu-system-riscv64 -machine virt \\"
190+
echo " -m 1024M -icount shift=0 -plugin /libinsn.so \\"
191+
echo " -kernel $OUTPUT -nographic \\"
190192
echo " -semihosting-config enable=on,target=native"
191193
echo ""
192194
else

platform/riscv-wamr-qemu/startup.S

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
_start:
55
la sp, _stack_top
66

7-
# Clear BSS section - using symbols defined in our linker script
7+
/* Clear BSS section - using symbols defined in our linker script */
88
la t0, _bss_start
99
la t1, _bss_end
1010
clear_bss:
@@ -14,8 +14,14 @@ clear_bss:
1414
j clear_bss
1515
bss_done:
1616

17-
# Jump to C code
17+
/* Call main */
1818
call main
1919

20-
# In case main returns
21-
1: j 1b
20+
/* https://github.com/xypron/riscv_test_payload (MIT-licensed) */
21+
li a7, 0x53525354 # SBI extension: SRST (System Reset)
22+
li a6, 0 # Function: system reset
23+
li a0, 0 # Reset type: shutdown
24+
li a1, 0 # Reset reason: no reason
25+
ecall # Perform system shutdown
26+
end:
27+
j end

platform/riscv-wamr-qemu/syscalls.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,6 @@ void* _sbrk(int incr) {
7070
}
7171

7272
// Required stubs
73-
void _exit(int code) { while (1); }
73+
void _exit(int code) {}
7474
int _kill(int pid, int sig) { return -1; }
7575
int _getpid(void) { return 1; }

platform/riscv-wamr-qemu/virt.ld

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ ENTRY(_start)
66

77
/* QEMU virt machine memory map */
88
MEMORY {
9-
ram (wxa) : ORIGIN = 0x80000000, LENGTH = 1024M
9+
ram (wxa) : ORIGIN = 0x80200000, LENGTH = 1024M
1010
}
1111

1212
SECTIONS
1313
{
1414
/* Start of RAM */
15-
. = 0x80000000;
15+
. = 0x80200000;
1616

1717
/* Code section */
1818
.text : {

platform/riscv-wamr-qemu/wamr-platform/baremetal_clock.c

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)