Skip to content

Commit 827fbd4

Browse files
authored
Merge pull request #808 from jprendes/benchmark-memory
Benchmark memory
2 parents afe5c9c + ddcaca3 commit 827fbd4

File tree

3 files changed

+123
-4
lines changed

3 files changed

+123
-4
lines changed

.github/workflows/benchmarks.yml

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ jobs:
1717

1818
steps:
1919
- uses: actions/checkout@v4
20-
- name: Fetch submodules
21-
run: git submodule update --init --recursive
2220
- uses: actions-rust-lang/setup-rust-toolchain@v1
2321
with:
2422
rustflags: '' #Disable. By default this action sets environment variable is set to -D warnings. We manage this in the Makefile
@@ -54,14 +52,56 @@ jobs:
5452
# Automatically push the benchmark result to gh-pages branch
5553
# See https://github.com/benchmark-action/github-action-benchmark?tab=readme-ov-file#charts-on-github-pages-1 for more details
5654
auto-push: ${{ github.event_name == 'schedule' }}
55+
56+
benchmark-mem:
57+
runs-on: ubuntu-latest
58+
59+
steps:
60+
- uses: actions/checkout@v4
61+
- uses: actions-rust-lang/setup-rust-toolchain@v1
62+
with:
63+
rustflags: '' #Disable. By default this action sets environment variable is set to -D warnings. We manage this in the Makefile
64+
- name: Setup build environment
65+
shell: bash
66+
run: |
67+
os=$(echo "$RUNNER_OS" | tr '[:upper:]' '[:lower:]')
68+
./scripts/setup-$os.sh
69+
- name: Build and load shims and wasi-demo-app
70+
shell: bash
71+
run: |
72+
make OPT_PROFILE=release build install test-image load test-image/oci load/oci
73+
- name: Run Benchmarks
74+
shell: bash
75+
run: |
76+
set -euxo pipefail
77+
for RUNTIME in wasmtime wasmedge wasmer wamr; do
78+
sudo ./scripts/benchmark-mem.sh $RUNTIME > bench-mem-$RUNTIME.json
79+
done
80+
cat bench-mem-* | jq -s 'flatten(1)' > bench-mem.json
81+
- name: Store benchmark result
82+
uses: benchmark-action/[email protected]
83+
with:
84+
name: Criterion.rs Benchmark
85+
tool: 'customSmallerIsBetter'
86+
output-file-path: bench-mem.json
87+
github-token: ${{ secrets.GITHUB_TOKEN }}
88+
# my experimental local benchmarking seems to have a 20% margin of error.
89+
# So I set the alert threshold to 130% of the previous benchmark result.
90+
# If the current benchmark result is more than 130% of the previous benchmark result, it will fail.
91+
alert-threshold: '130%'
92+
fail-on-alert: ${{ github.event_name == 'schedule' }}
93+
alert-comment-cc-users: '@runwasi-committers'
94+
# Enable Job Summary
95+
summary-always: true
96+
# Automatically push the benchmark result to gh-pages branch
97+
# See https://github.com/benchmark-action/github-action-benchmark?tab=readme-ov-file#charts-on-github-pages-1 for more details
98+
auto-push: ${{ github.event_name == 'schedule' }}
5799

58100
benchmark-http:
59101
runs-on: ubuntu-latest
60102

61103
steps:
62104
- uses: actions/checkout@v4
63-
- name: Fetch submodules
64-
run: git submodule update --init --recursive
65105
- uses: actions-rust-lang/setup-rust-toolchain@v1
66106
with:
67107
rustflags: '' #Disable. By default this action sets environment variable is set to -D warnings. We manage this in the Makefile

crates/containerd-shim-wasm/src/sandbox/cli.rs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,42 @@ macro_rules! revision {
3232
};
3333
}
3434

35+
#[cfg(target_os = "linux")]
36+
fn get_mem(pid: u32) -> (usize, usize) {
37+
let mut rss = 0;
38+
let mut total = 0;
39+
for line in std::fs::read_to_string(format!("/proc/{pid}/status"))
40+
.unwrap()
41+
.lines()
42+
{
43+
let line = line.trim();
44+
// VmPeak is the maximum total virtual memory used so far.
45+
// VmHWM (high water mark) is the maximum resident set memory used so far.
46+
// See: https://man7.org/linux/man-pages/man5/proc_pid_status.5.html
47+
if let Some(rest) = line.strip_prefix("VmPeak:") {
48+
if let Some(rest) = rest.strip_suffix("kB") {
49+
total = rest.trim().parse().unwrap_or(0);
50+
}
51+
} else if let Some(rest) = line.strip_prefix("VmHWM:") {
52+
if let Some(rest) = rest.strip_suffix("kB") {
53+
rss = rest.trim().parse().unwrap_or(0);
54+
}
55+
}
56+
}
57+
(rss, total)
58+
}
59+
60+
#[cfg(target_os = "linux")]
61+
fn log_mem() {
62+
let pid = std::process::id();
63+
let (rss, tot) = get_mem(pid);
64+
log::info!("Shim peak memory usage was: peak resident set {rss} kB, peak total {tot} kB");
65+
66+
let pid = zygote::Zygote::global().run(|_| std::process::id(), ());
67+
let (rss, tot) = get_mem(pid);
68+
log::info!("Zygote peak memory usage was: peak resident set {rss} kB, peak total {tot} kB");
69+
}
70+
3571
/// Main entry point for the shim.
3672
///
3773
/// If the `opentelemetry` feature is enabled, this function will start the shim with OpenTelemetry tracing.
@@ -70,6 +106,9 @@ pub fn shim_main<'a, I>(
70106
{
71107
shim_main_inner::<I>(name, version, revision, shim_version, config);
72108
}
109+
110+
#[cfg(target_os = "linux")]
111+
log_mem();
73112
}
74113

75114
#[cfg_attr(feature = "tracing", tracing::instrument(parent = tracing::Span::current(), skip_all, level = "Info"))]

scripts/benchmark-mem.sh

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
3+
set -euxo pipefail
4+
5+
# Parse CLI arguments
6+
RUNTIME=${1:-"wasmtime"}; shift || true
7+
IMAGE=${1:-"ghcr.io/containerd/runwasi/wasi-demo-app:latest"}; shift || true
8+
9+
if [ $IMAGE == "ghcr.io/containerd/runwasi/wasi-demo-app:latest" ] && [ "$#" == "0" ]; then
10+
set -- /wasi-demo-app.wasm echo 'hello'
11+
fi
12+
13+
# Run the shim and collect logs
14+
LOG_FILE=$(mktemp)
15+
journalctl -fn 0 -u containerd | timeout -k 16s 15s grep -m 2 'peak memory usage was' > $LOG_FILE &
16+
ctr run --null-io --rm --runtime=io.containerd.$RUNTIME.v1 "$IMAGE" testwasm "$@"
17+
18+
# Parse the logs
19+
wait
20+
SHIM_MEM=$(cat $LOG_FILE | grep 'Shim peak memory usage was' | sed -E 's/.*peak resident set ([0-9]+) kB.*/\1/')
21+
ZYGOTE_MEM=$(cat $LOG_FILE | grep 'Zygote peak memory usage was' | sed -E 's/.*peak resident set ([0-9]+) kB.*/\1/')
22+
rm $LOG_FILE
23+
24+
if [ "$SHIM_MEM" == "" ] || [ "$ZYGOTE_MEM" == "" ]; then
25+
exit 1
26+
fi
27+
28+
TOTAL_MEM=$(( $SHIM_MEM + $ZYGOTE_MEM ))
29+
30+
# Print the JSON for the benchmark report
31+
cat <<EOF
32+
[
33+
{
34+
"name": "$RUNTIME/memory-usage",
35+
"unit": "kB",
36+
"value": $TOTAL_MEM,
37+
"extra": "shim: $SHIM_MEM kB\nzygote: $ZYGOTE_MEM kB"
38+
}
39+
]
40+
EOF

0 commit comments

Comments
 (0)