From a37462fbbc69890f972d1b468e7db4943c60c80c Mon Sep 17 00:00:00 2001 From: Johnnie Birch Date: Thu, 20 Jul 2023 15:48:08 -0700 Subject: [PATCH 1/4] Fix native run script to grab any and all potential input files (#265) --- benchmarks/run-native.sh | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/benchmarks/run-native.sh b/benchmarks/run-native.sh index 463987f..85483cb 100755 --- a/benchmarks/run-native.sh +++ b/benchmarks/run-native.sh @@ -34,8 +34,7 @@ TMP_BENCHMARK_DIR=/tmp/sightglass-benchmark-native-$MD5SUM mkdir -p $TMP_BENCHMARK_DIR (set -x; ln -fs $BENCHMARK_NATIVE_SO $TMP_BENCHMARK_DIR/benchmark.so) BENCHMARK_DIR=$(dirname $BENCHMARK_NATIVE_SO) -NAME=$(basename $BENCHMARK_NATIVE_SO .so); -for FILE in $(find $BENCHMARK_DIR -name "$NAME*.input"); do +for FILE in $(find $BENCHMARK_DIR -name "*.input"); do (set -x; ln -fs $FILE $TMP_BENCHMARK_DIR/) done From 9b0039a7f7e1fc79919c37a8af173542429217b1 Mon Sep 17 00:00:00 2001 From: Johnnie Birch Date: Thu, 20 Jul 2023 15:51:36 -0700 Subject: [PATCH 2/4] Add's native support for meshoptimizer (#264) * Add's native support for meshoptimizer * Add .gitignore and dockerfile for meshoptimizer native --- benchmarks/meshoptimizer/.gitignore | 1 + benchmarks/meshoptimizer/Dockerfile.native | 21 ++++ benchmarks/meshoptimizer/build-native.sh | 15 +++ .../meshoptimizer/sightglass.native.patch | 111 ++++++++++++++++++ 4 files changed, 148 insertions(+) create mode 100644 benchmarks/meshoptimizer/.gitignore create mode 100644 benchmarks/meshoptimizer/Dockerfile.native create mode 100755 benchmarks/meshoptimizer/build-native.sh create mode 100644 benchmarks/meshoptimizer/sightglass.native.patch diff --git a/benchmarks/meshoptimizer/.gitignore b/benchmarks/meshoptimizer/.gitignore new file mode 100644 index 0000000..9f7c0cf --- /dev/null +++ b/benchmarks/meshoptimizer/.gitignore @@ -0,0 +1 @@ +*/meshoptimizer \ No newline at end of file diff --git a/benchmarks/meshoptimizer/Dockerfile.native b/benchmarks/meshoptimizer/Dockerfile.native new file mode 100644 index 0000000..5afffc6 --- /dev/null +++ b/benchmarks/meshoptimizer/Dockerfile.native @@ -0,0 +1,21 @@ +FROM ubuntu:20.04 +ENV DEBIAN_FRONTEND="noninteractive" TZ="America" +RUN apt update && apt-get install -y --no-install-recommends wget build-essential git ca-certificates + +# Install clang +RUN apt-get install -y --no-install-recommends clang + +# Copy in the `src` directory. +ENV SRC=/usr/src/meshoptimizer/ +WORKDIR $SRC +COPY sightglass.h sightglass.native.patch ./ +COPY build-native.sh . +COPY libengine.so /usr/lib/ + +# Compile each of the benchmarks into the `/benchmark` directory. +RUN ./build-native.sh + +# We copy the shared libraries to the `/benchmark` directory, where the client +# expects it. +WORKDIR /benchmark +RUN cp $SRC/*so . diff --git a/benchmarks/meshoptimizer/build-native.sh b/benchmarks/meshoptimizer/build-native.sh new file mode 100755 index 0000000..78f93ce --- /dev/null +++ b/benchmarks/meshoptimizer/build-native.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env bash + +# Build all of the shootout benchmarks as native shared libraries (Linux-only). +# +# Usage: ./build-native.sh + +(set -x); +(rm -r -f meshoptimizer); +(git clone --recurse-submodules https://github.com/zeux/meshoptimizer.git); +(cd meshoptimizer; git reset --hard f734fd572aed5bf76e84d9ed62ca6f4f6c47d84e; cd -); +(cp sightglass.h sightglass.native.patch meshoptimizer/); +(cd meshoptimizer; patch -Np1 -i ./sightglass.native.patch; cd -); +(cd meshoptimizer; CXX=/usr/bin/clang++ make codecbench-simd.so ; cd -); +(set +x); + diff --git a/benchmarks/meshoptimizer/sightglass.native.patch b/benchmarks/meshoptimizer/sightglass.native.patch new file mode 100644 index 0000000..821af6e --- /dev/null +++ b/benchmarks/meshoptimizer/sightglass.native.patch @@ -0,0 +1,111 @@ +diff --git a/Makefile b/Makefile +index 6697c13..26e637f 100644 +--- a/Makefile ++++ b/Makefile +@@ -20,7 +20,9 @@ LIBRARY=$(BUILD)/libmeshoptimizer.a + DEMO=$(BUILD)/meshoptimizer + + CFLAGS=-g -Wall -Wextra -Werror -std=c89 +-CXXFLAGS=-g -Wall -Wextra -Wshadow -Wno-missing-field-initializers -Werror -std=c++98 ++CXXFLAGS=-O3 -Wall -Wextra -Wshadow -Wno-missing-field-initializers -Werror -std=c++17 -fPIC ++CXXFLAGS_SIGHTGLASS=-O3 -Wall -Wextra -Wshadow -Wno-missing-field-initializers \ ++ -std=c++17 -Dmain=native_entry -fno-exceptions -fPIC -I. -L../../../engines/native/ -shared + LDFLAGS= + + $(GLTFPACK_OBJECTS): CXXFLAGS+=-std=c++11 +@@ -167,6 +169,9 @@ codecbench.wasm: tools/codecbench.cpp ${LIBRARY_SOURCES} + codecbench-simd.wasm: tools/codecbench.cpp ${LIBRARY_SOURCES} + $(WASMCC) $^ -fno-exceptions --target=wasm32-wasi --sysroot=$(WASIROOT) -lc++ -lc++abi -O3 -g -DNDEBUG -msimd128 -o $@ + ++codecbench-simd.so: $(LIBRARY_OBJECTS) ++ $(CXX) $^ $(CXXFLAGS_SIGHTGLASS) $(LDFLAGS) tools/codecbench.cpp -o ../codecbench-simd.so -lengine ++ + codecfuzz: tools/codecfuzz.cpp src/vertexcodec.cpp src/indexcodec.cpp + $(CXX) $^ -fsanitize=fuzzer,address,undefined -O1 -g -o $@ + +diff --git a/tools/codecbench.cpp b/tools/codecbench.cpp +index 350cb9c..f06bcff 100644 +--- a/tools/codecbench.cpp ++++ b/tools/codecbench.cpp +@@ -1,4 +1,5 @@ + #include "../src/meshoptimizer.h" ++#include "../sightglass.h" + + #include + +@@ -161,15 +162,12 @@ void benchFilters(size_t count, double& besto8, double& besto12, double& bestq12 + } + } + +-int main(int argc, char** argv) ++extern "C" { ++int main() + { + meshopt_encodeIndexVersion(1); + +- bool verbose = false; +- +- for (int i = 1; i < argc; ++i) +- if (strcmp(argv[i], "-v") == 0) +- verbose = true; ++ bool verbose = true; + + const int N = 1000; + +@@ -212,13 +210,21 @@ int main(int argc, char** argv) + } + } + ++ bench_start(); ++ + double bestvd = 0, bestid = 0; + benchCodecs(vertices, indices, bestvd, bestid, verbose); + + double besto8 = 0, besto12 = 0, bestq12 = 0, bestexp = 0; + benchFilters(8 * N * N, besto8, besto12, bestq12, bestexp, verbose); + ++ bench_end(); ++ + printf("Algorithm :\tvtx\tidx\toct8\toct12\tquat12\texp\n"); +- printf("Score (GB/s):\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n", +- bestvd, bestid, besto8, besto12, bestq12, bestexp); ++ if (verbose) ++ printf("Score (GB/s):\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\t%.2f\n", ++ bestvd, bestid, besto8, besto12, bestq12, bestexp); ++ ++ return 0; + } ++} +\ No newline at end of file +diff --git a/sightglass.h b/sightglass.h +index a767e9e..f12c956 100644 +--- a/sightglass.h ++++ b/sightglass.h +@@ -8,7 +8,13 @@ + */ + __attribute__((import_module("bench"))) + __attribute__((import_name("start"))) ++#ifdef __cplusplus ++extern "C" { ++#endif + void bench_start(); ++#ifdef __cplusplus ++} ++#endif + + /** + * Call this function to indicate that recording should end. This call should be placed immediately +@@ -17,7 +23,13 @@ void bench_start(); + */ + __attribute__((import_module("bench"))) + __attribute__((import_name("end"))) ++#ifdef __cplusplus ++extern "C" { ++#endif + void bench_end(); ++#ifdef __cplusplus ++} ++#endif + + /** + * Call this function to prevent certain compiler-related optimizations related to knowing the value \ No newline at end of file From e89fce09ce39af27f5519b80dc4f4fe4801e24ba Mon Sep 17 00:00:00 2001 From: Johnnie Birch Date: Thu, 20 Jul 2023 17:31:21 -0700 Subject: [PATCH 3/4] Add native support for regex benchmark (#266) * Add native support for regex benchmark * Remove comments in Dockerfile.native for regex --- benchmarks/regex/.gitignore | 1 + benchmarks/regex/Dockerfile.native | 17 +++++++ benchmarks/regex/build-native.sh | 13 ++++++ benchmarks/regex/sightglass.native.patch | 59 ++++++++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100644 benchmarks/regex/.gitignore create mode 100644 benchmarks/regex/Dockerfile.native create mode 100755 benchmarks/regex/build-native.sh create mode 100644 benchmarks/regex/sightglass.native.patch diff --git a/benchmarks/regex/.gitignore b/benchmarks/regex/.gitignore new file mode 100644 index 0000000..972491a --- /dev/null +++ b/benchmarks/regex/.gitignore @@ -0,0 +1 @@ +/rust-benchmark-native/ \ No newline at end of file diff --git a/benchmarks/regex/Dockerfile.native b/benchmarks/regex/Dockerfile.native new file mode 100644 index 0000000..39ef1e9 --- /dev/null +++ b/benchmarks/regex/Dockerfile.native @@ -0,0 +1,17 @@ +FROM rust:1.70 + +# Copy in the `src` directory. +ENV SRC=/usr/src/regex/ +WORKDIR $SRC +ADD rust-benchmark rust-benchmark +COPY sightglass.native.patch ./ +COPY build-native.sh . +COPY libengine.so /usr/lib/ + +# Compile each of the benchmarks into the `/benchmark` directory. +RUN ./build-native.sh + +# We copy the shared libraries to the `/benchmark` directory, where the client +# expects it. +WORKDIR /benchmark +RUN cp $SRC/*so . diff --git a/benchmarks/regex/build-native.sh b/benchmarks/regex/build-native.sh new file mode 100755 index 0000000..ad5d0c6 --- /dev/null +++ b/benchmarks/regex/build-native.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +# Build regex benchmark as native shared libraries (Linux-only). +# +# Usage: ./build-native.sh + +(set -x;) +(rm -rf rust-benchmark-native); +(cp -r rust-benchmark rust-benchmark-native/); +(cp sightglass.native.patch rust-benchmark-native/); +(cd rust-benchmark-native; patch -Np1 -i ./sightglass.native.patch; cd -); +(cd rust-benchmark-native; cargo build --release; cp target/release/libbenchmark.so ../benchmark.so; cd -); +(set +x;) diff --git a/benchmarks/regex/sightglass.native.patch b/benchmarks/regex/sightglass.native.patch new file mode 100644 index 0000000..4ba88f4 --- /dev/null +++ b/benchmarks/regex/sightglass.native.patch @@ -0,0 +1,59 @@ +diff --git a/Cargo.toml b/Cargo.toml +index ee59a1c..dbeccb7 100644 +--- a/Cargo.toml ++++ b/Cargo.toml +@@ -8,3 +8,6 @@ regex = "1.7.1" + sightglass-api = "0.1" + + [workspace] ++ ++[lib] ++crate-type = ["cdylib"] +\ No newline at end of file +diff --git a/build.rs b/build.rs +new file mode 100644 +index 0000000..6d7d743 +--- /dev/null ++++ b/build.rs +@@ -0,0 +1,3 @@ ++fn main() { ++ println!("cargo:rustc-cdylib-link-arg=-L../../../engines/native/"); ++} +diff --git a/src/main.rs b/src/lib.rs +similarity index 84% +rename from src/main.rs +rename to src/lib.rs +index a1ef2f8..0bf007d 100644 +--- a/src/main.rs ++++ b/src/lib.rs +@@ -13,16 +13,27 @@ const URI_PATTERN: &str = r"[\w]+://[^/\s?#]+[^\s?#]+(?:\?[^\s#]*)?(?:#[^\s]*)?" + const IP_PATTERN: &str = + r"(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9])"; + +-fn main() { ++#[link(name = "engine")] ++extern "C" { ++ fn bench_start() -> (); ++ fn bench_end() -> (); ++} ++ ++#[no_mangle] ++pub extern "C" fn native_entry() { + let path = "default.input"; + eprintln!("[regex] matching {}", path); + let data = std::fs::read_to_string(path).expect("unable to find `*.input` text file"); + +- bench::start(); ++ unsafe { ++ bench_start(); ++ } + let emails = count_matches(&data, EMAIL_PATTERN); + let uris = count_matches(&data, URI_PATTERN); + let ips = count_matches(&data, IP_PATTERN); +- bench::end(); ++ unsafe { ++ bench_end(); ++ } + + eprintln!("[regex] found {} emails", emails); + eprintln!("[regex] found {} URIs", uris); From b1a74731eca13a05182ebb32377ad1169bd3a96e Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Tue, 26 Sep 2023 13:53:18 -0700 Subject: [PATCH 4/4] Add `simd.suite` (#268) As discussed in a Cranelift meeting, it would be nice to know which benchmarks are SIMD users. This change adds a `simd.suite` file that lists the files that contain SIMD instructions. This can be run like: ```console $ cargo run -- benchmark --engine .../libengine.so benchmarks/simd.suite ``` There are a couple ways this could be improved, but this may be fine as-is for now: - `simd.suite` could get out of date; someone could create a CI check to keep it in-sync with the added files - someone could really check that the measured section of each benchmark is actually a heavy SIMD user by collecting the instruction mix (e.g., `sde`) --- benchmarks/simd.suite | 89 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 benchmarks/simd.suite diff --git a/benchmarks/simd.suite b/benchmarks/simd.suite new file mode 100644 index 0000000..1da1539 --- /dev/null +++ b/benchmarks/simd.suite @@ -0,0 +1,89 @@ +# These benchmarks use WebAssembly SIMD instructions. Inclusion in this list +# does not guarantee that the benchmark is a SIMD-centric workload in the +# measured section, only that SIMD instructions are present. +# +# These files were gathered by: +# - creating a `find-simd.sh` script containing: `wasm2wat --disable-simd $1 +# &>/dev/null || echo $1` +# - running the script over the benchmarks: `find . -name '*.wasm' | xargs -L 1 +# ./find-simd.sh` + +blake3-simd/benchmark.wasm +hex-simd/benchmark.wasm +intgemm-simd/benchmark.wasm +meshoptimizer/benchmark.wasm +libsodium/libsodium-aead_aes256gcm.wasm +libsodium/libsodium-aead_aes256gcm2.wasm +libsodium/libsodium-aead_chacha20poly1305.wasm +libsodium/libsodium-aead_chacha20poly13052.wasm +libsodium/libsodium-aead_xchacha20poly1305.wasm +libsodium/libsodium-auth.wasm +libsodium/libsodium-auth2.wasm +libsodium/libsodium-auth3.wasm +libsodium/libsodium-auth5.wasm +libsodium/libsodium-auth6.wasm +libsodium/libsodium-auth7.wasm +libsodium/libsodium-box.wasm +libsodium/libsodium-box2.wasm +libsodium/libsodium-box7.wasm +libsodium/libsodium-box8.wasm +libsodium/libsodium-box_easy.wasm +libsodium/libsodium-box_easy2.wasm +libsodium/libsodium-box_seal.wasm +libsodium/libsodium-box_seed.wasm +libsodium/libsodium-chacha20.wasm +libsodium/libsodium-codecs.wasm +libsodium/libsodium-core1.wasm +libsodium/libsodium-core2.wasm +libsodium/libsodium-core3.wasm +libsodium/libsodium-core4.wasm +libsodium/libsodium-core5.wasm +libsodium/libsodium-core6.wasm +libsodium/libsodium-core_ed25519.wasm +libsodium/libsodium-core_ristretto255.wasm +libsodium/libsodium-ed25519_convert.wasm +libsodium/libsodium-generichash.wasm +libsodium/libsodium-generichash2.wasm +libsodium/libsodium-generichash3.wasm +libsodium/libsodium-hash.wasm +libsodium/libsodium-hash3.wasm +libsodium/libsodium-kdf.wasm +libsodium/libsodium-keygen.wasm +libsodium/libsodium-kx.wasm +libsodium/libsodium-metamorphic.wasm +libsodium/libsodium-misuse.wasm +libsodium/libsodium-onetimeauth.wasm +libsodium/libsodium-onetimeauth2.wasm +libsodium/libsodium-onetimeauth7.wasm +libsodium/libsodium-pwhash_argon2i.wasm +libsodium/libsodium-pwhash_argon2id.wasm +libsodium/libsodium-pwhash_scrypt.wasm +libsodium/libsodium-pwhash_scrypt_ll.wasm +libsodium/libsodium-randombytes.wasm +libsodium/libsodium-scalarmult.wasm +libsodium/libsodium-scalarmult2.wasm +libsodium/libsodium-scalarmult5.wasm +libsodium/libsodium-scalarmult6.wasm +libsodium/libsodium-scalarmult7.wasm +libsodium/libsodium-scalarmult8.wasm +libsodium/libsodium-scalarmult_ed25519.wasm +libsodium/libsodium-scalarmult_ristretto255.wasm +libsodium/libsodium-secretbox.wasm +libsodium/libsodium-secretbox2.wasm +libsodium/libsodium-secretbox7.wasm +libsodium/libsodium-secretbox8.wasm +libsodium/libsodium-secretbox_easy.wasm +libsodium/libsodium-secretbox_easy2.wasm +libsodium/libsodium-secretstream.wasm +libsodium/libsodium-shorthash.wasm +libsodium/libsodium-sign.wasm +libsodium/libsodium-siphashx24.wasm +libsodium/libsodium-sodium_core.wasm +libsodium/libsodium-sodium_utils.wasm +libsodium/libsodium-sodium_version.wasm +libsodium/libsodium-stream.wasm +libsodium/libsodium-stream2.wasm +libsodium/libsodium-stream3.wasm +libsodium/libsodium-stream4.wasm +libsodium/libsodium-verify1.wasm +libsodium/libsodium-xchacha20.wasm