diff --git a/benchmarks/micromm/base.yaml b/benchmarks/micromm/base.yaml index d844cc60352c0c99bb75bb688db686d49b5bc073..51ab6ae13619051cc6c4f02479407f926fb1be53 100644 --- a/benchmarks/micromm/base.yaml +++ b/benchmarks/micromm/base.yaml @@ -1,2 +1,2 @@ suite: micromm -image: registry.gitlab.arm.com/tooling/fastpath/containers/micromm:v1.0 +image: registry.gitlab.arm.com/tooling/fastpath/containers/microbench:v1.0 diff --git a/benchmarks/syscall/base.yaml b/benchmarks/syscall/base.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8164c5fcb0bdec65c0c959c5306da101a6890732 --- /dev/null +++ b/benchmarks/syscall/base.yaml @@ -0,0 +1,4 @@ +suite: syscall +image: registry.gitlab.arm.com/tooling/fastpath/containers/microbench:v1.0 +params: + iterations: 10000000 diff --git a/benchmarks/syscall/getpid.yaml b/benchmarks/syscall/getpid.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e07fd34acf29944e64ab20ee0fdfe7a2a974079f --- /dev/null +++ b/benchmarks/syscall/getpid.yaml @@ -0,0 +1,5 @@ +include: base.yaml +name: getpid +type: micro +params: + syscall: getpid diff --git a/benchmarks/syscall/getppid.yaml b/benchmarks/syscall/getppid.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8aaf02e01dd416cdc9f0efeda6c761ed2eb5cf96 --- /dev/null +++ b/benchmarks/syscall/getppid.yaml @@ -0,0 +1,5 @@ +include: base.yaml +name: getppid +type: micro +params: + syscall: getppid diff --git a/benchmarks/syscall/invalid.yaml b/benchmarks/syscall/invalid.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b15e2a982b936904b2145330c66c8bf9afbcc87f --- /dev/null +++ b/benchmarks/syscall/invalid.yaml @@ -0,0 +1,5 @@ +include: base.yaml +name: invalid +type: micro +params: + syscall: invalid diff --git a/containers/micromm/Dockerfile b/containers/microbench/Dockerfile similarity index 88% rename from containers/micromm/Dockerfile rename to containers/microbench/Dockerfile index 06df9f6a3c87959fd9b87548b24eb6747b2f8685..0e5ff276c977fff69e61ef35b13ef2f7e1996d82 100644 --- a/containers/micromm/Dockerfile +++ b/containers/microbench/Dockerfile @@ -28,13 +28,19 @@ RUN apt-get update && \ apt-get install --assume-yes --no-install-recommends --option=debug::pkgProblemResolver=yes \ kmod -# Compile the micromm benchmark program. ARG NAME -COPY containers/${NAME}/micromm.c /tmp/micromm.c RUN mkdir /fastpath + +# Compile the micromm benchmark program. +COPY containers/${NAME}/micromm.c /tmp/micromm.c RUN gcc /tmp/micromm.c -O2 -o /fastpath/micromm RUN rm -rf /tmp/micromm.c +# Compile the syscall benchmark program. +COPY containers/${NAME}/syscall.c /tmp/syscall.c +RUN gcc /tmp/syscall.c -O2 -o /fastpath/syscall +RUN rm -rf /tmp/syscall.c + # Setup the entrypoint. COPY containers/${NAME}/exec.py /fastpath/. CMD /fastpath/exec.py diff --git a/containers/micromm/exec.py b/containers/microbench/exec.py similarity index 84% rename from containers/micromm/exec.py rename to containers/microbench/exec.py index 2ee800c1f2f9eebd6e85df901592ce13f8e4df9f..d85631b3f5c1244280774f3f7c588dbb14bce3ff 100755 --- a/containers/micromm/exec.py +++ b/containers/microbench/exec.py @@ -28,31 +28,38 @@ result_header = [ def validate_benchmark(benchmark): - if benchmark["suite"] != "micromm": + if benchmark["suite"] not in ["micromm", "syscall"]: return ERR_INVAL_BENCHMARK_FORMAT params = benchmark.get("params", {}) - if benchmark["name"] == "vmalloc": - # vmalloc test. - if params and "test_case" not in params: - return ERR_INVAL_BENCHMARK_FORMAT - - found_module = ( - subprocess.run( - "modinfo test_vmalloc", - shell=True, - check=False, - capture_output=True, - ).returncode - == 0 - ) - - if not found_module: - return ERR_BENCHMARK_FAIL + if benchmark["suite"] == "micromm": + if benchmark["name"] == "vmalloc": + # vmalloc test. + if params and "test_case" not in params: + return ERR_INVAL_BENCHMARK_FORMAT + + found_module = ( + subprocess.run( + "modinfo test_vmalloc", + shell=True, + check=False, + capture_output=True, + ).returncode + == 0 + ) + + if not found_module: + return ERR_BENCHMARK_FAIL + else: + # micromm tests. + if "mode" not in params: + return ERR_INVAL_BENCHMARK_FORMAT else: - # micromm tests. - if "mode" not in params: + # syscall tests. + if "syscall" not in params: + return ERR_INVAL_BENCHMARK_FORMAT + if "iterations" not in params: return ERR_INVAL_BENCHMARK_FORMAT return ERR_NONE @@ -343,6 +350,39 @@ def test_micromm(test, outdir): } +def syscall_params_to_descs(params): + return [params] + + +def test_syscall(test, outdir): + cmd = f"/fastpath/syscall {test['syscall']} {test['iterations']}" + + log = subprocess.run( + cmd, + shell=True, + check=True, + capture_output=True, + text=True, + ).stdout.strip() + + with open(os.path.join(outdir, "syscall.log"), "a") as logfile: + logfile.write(f"{cmd}\n") + logfile.write(log) + logfile.write("\n\n") + + parts = log.split(" ") + duration = float(parts[0].strip()) + unit = parts[1].strip() + + return { + "name": "duration", + "value": duration, + "error": ERR_NONE, + "unit": unit, + "improvement": "smaller", + } + + def make_error(errno): error = {k: None for k in result_header} error["error"] = errno @@ -367,7 +407,10 @@ def main(): outdir = os.path.join(os.path.abspath(args.fastpath_share), "output") params = benchmark.get("params", {}) - if benchmark["name"] == "vmalloc": + if benchmark["suite"] == "syscall": + params_to_descs_fn = syscall_params_to_descs + test_fn = test_syscall + elif benchmark["name"] == "vmalloc": params_to_descs_fn = vmalloc_params_to_descs test_fn = test_vmalloc else: diff --git a/containers/micromm/micromm.c b/containers/microbench/micromm.c similarity index 100% rename from containers/micromm/micromm.c rename to containers/microbench/micromm.c diff --git a/containers/microbench/syscall.c b/containers/microbench/syscall.c new file mode 100644 index 0000000000000000000000000000000000000000..36c449ba602247f3066e428e16c6459b1d794bd7 --- /dev/null +++ b/containers/microbench/syscall.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include +#include +#include +#include + +#define INVAL_SYSCALL (-1) + +void usage(void) +{ + fprintf(stderr, "Usage: syscall [getpid|getppid|invalid] \n"); + exit(1); +} + +int main(int argc, char *argv[]) +{ + long syscall_id; + long iterations; + struct timespec start, end; + + if (argc != 3) + usage(); + if (!strcmp(argv[1], "getpid")) + syscall_id = SYS_getpid; + else if (!strcmp(argv[1], "getppid")) + syscall_id = SYS_getppid; + else if (!strcmp(argv[1], "invalid")) + syscall_id = INVAL_SYSCALL; + else + usage(); + + iterations = strtoul(argv[2], NULL, 10); + + clock_gettime(CLOCK_MONOTONIC, &start); + for (long i = 0; i < iterations; i++) + syscall(syscall_id); + clock_gettime(CLOCK_MONOTONIC, &end); + + double elapsed = (end.tv_sec - start.tv_sec) + + (end.tv_nsec - start.tv_nsec) / 1e9; + elapsed = (elapsed / iterations) * 1000000; + printf("%f us\n", elapsed); + return 0; +}