diff --git a/.github/workflows/platform.yml b/.github/workflows/platform.yml index 6f86c7e..c75b123 100644 --- a/.github/workflows/platform.yml +++ b/.github/workflows/platform.yml @@ -70,9 +70,10 @@ jobs: # sm: ../src/supermalloc.h:10:31: error: expected initializer before '__THROW' - allocator: sm predicate: ${{ inputs.platform == 'alpine' }} - # tcg: [...] specifies less restrictive attribute than its target [...] + # tcg: needs bazel, which is only installed for ubuntu; on alpine + # tcmalloc also fails to compile with clang - allocator: tcg - predicate: ${{ inputs.platform == 'alpine' }} + predicate: ${{ inputs.platform != 'ubuntu' }} fail-fast: false name: ${{ matrix.allocator }} - build and benchmark steps: @@ -85,6 +86,12 @@ jobs: - name: Unload host AppArmor profiles run: sudo aa-teardown || true + # Some tests (e.g. sh6bench) keep tens of thousands of allocations live at + # once and some allocators (e.g. hardened_malloc) map guard pages per + # allocation, so they hit vm.max_map_count. Increase to make them pass. + - name: Raise vm.max_map_count for the benchmarks + run: sudo sysctl -w vm.max_map_count=1048576 + - name: Build allocator and run benchmarks in Docker id: docker_build uses: docker/build-push-action@v7 diff --git a/.gitignore b/.gitignore index f16f800..f623cc7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +archives/ extern/ out/ bench/doc/ diff --git a/Dockerfile b/Dockerfile index d7d4a2b..d2d7c32 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,38 @@ ARG platform=ubuntu FROM ubuntu:24.04 AS ubuntu - +RUN apt-get update +RUN apt-get install -y --no-install-recommends build-essential git gpg \ + g++ clang lld llvm-dev unzip dos2unix linuxinfo bc libgmp-dev wget \ + cmake python3 ruby ninja-build libtool autoconf sed ghostscript \ + time curl automake libatomic1 libgflags-dev libsnappy-dev cargo \ + zlib1g-dev libbz2-dev liblz4-dev libzstd-dev libreadline-dev \ + pkg-config gawk util-linux bsdextrautils flex bison libelf-dev +# Install bazel +RUN apt-get install -y --no-install-recommends apt-transport-https curl gnupg +RUN curl -fsSL https://releases.bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel.gpg +RUN mv bazel.gpg /etc/apt/trusted.gpg.d/bazel.gpg +RUN echo "deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8" > /etc/apt/sources.list.d/bazel.list +RUN apt-get update && apt-get install bazel FROM fedora:44 AS fedora - +RUN dnf -y --quiet --nodocs install gcc-c++ clang lld llvm-devel unzip \ + dos2unix bc gmp-devel wget gawk cmake python3 ruby ninja-build libtool \ + autoconf git patch time sed ghostscript libatomic libstdc++ which \ + gflags-devel xz readline-devel snappy-devel rust flex bison elfutils-libelf-devel +# Install bazel - off for now, only tcg needs it and that's not building anyway +#RUN dnf -y --quiet copr enable ohadm/bazel +#RUN dnf -y --quiet --nodocs install bazel8 FROM alpine:3.24 AS alpine +RUN echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories +RUN apk update RUN apk add --no-cache bash - +RUN apk add -q clang lld unzip dos2unix bc gmp-dev wget cmake python3 ruby \ + automake gawk samurai libtool git build-base linux-headers autoconf \ + util-linux sed ghostscript libatomic gflags-dev readline-dev snappy-dev cargo \ + flex bison elfutils-dev +RUN apk add -q bazel@testing FROM ${platform} AS bench-env @@ -17,19 +41,13 @@ RUN mkdir -p /mimalloc-bench COPY . /mimalloc-bench WORKDIR /mimalloc-bench -# Install dependencies -RUN ./build-bench-env.sh packages - -# Build benchmarks -RUN ./build-bench-env.sh bench - -RUN ./build-bench-env.sh redis - -RUN ./build-bench-env.sh rocksdb - -RUN ./build-bench-env.sh lean -RUN ./build-bench-env.sh linux +RUN make benchmarks +RUN make redis +RUN make rocksdb +RUN make lean +RUN make lua +RUN make linux FROM bench-env AS benchmark @@ -39,8 +57,8 @@ ARG allocator=mi ARG benchs=cfrac ARG repeats=1 -RUN ./build-bench-env.sh $allocator +RUN make $allocator # Run benchmarks WORKDIR /mimalloc-bench/out/bench -RUN ../../bench.sh $allocator $benchs -r=$repeats \ No newline at end of file +RUN ../../bench.sh $allocator $benchs -r=$repeats diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1eccf93 --- /dev/null +++ b/Makefile @@ -0,0 +1,350 @@ +SUDO=sudo +ifeq ($(shell whoami), root) +$(warning running as root, avoid doing this if possible.) +SUDO= +endif + +DARWIN=no +PROCS=$(shell nproc) +EXTSO=so +SHA256SUM=sha256sum +SHA256SUM_FLAGS=-c --status +ORIG= + +ifeq ($(shell uname), Darwin) +DARWIN=yes +PROCS=$(shell sysctl -n hw.physicalcpu) +EXTSO=dylib +SHA256SUM=shasum -a 256 +SHA256SUM_FLAGS=-c -s +export HOMEBREW_NO_EMOJI=1 +ORIG=_orig +endif + +ifneq ($(shell grep -e 'ID=alpine' /etc/os-release),) +SHA256SUM_FLAGS=-c -s +endif + +BENCHMARKS_EXTERN=lean linux lua mathlib redis rocksdb +ALLOCS = dh ff fg gd hd hm iso je kp lf lp lt mesh mi mi2 mi3 mng nomesh rmalloc rp s sc scudo sg sm sn tbb tc tcg yal +PDFDOC=extern/large.pdf + +######################################################################## +# Environment flags for the individual make processes, may just be the # +# respective target name. # +######################################################################## + +fg_ENV=SSE2RNG=1 +iso_ENV=library +mesh_ENV=build +lf_ENV=liblite-malloc-shared.so +lt_ENV=-C gnu.make.lib +hd_ENV=-C src +redis_ENV=USE_JEMALLOC=no MALLOC=libc BUILD_TLS=no -C src +rocksdb_ENV=DISABLE_WARNING_AS_ERROR=1 DISABLE_JEMALLOC=1 ROCKSDB_DISABLE_TCMALLOC=1 db_bench + +# TODO: Mac seems to report 'arm64' here +ifeq ($(shell uname -m), aarch64) +ALLOCS := $(filter-out fg lt mesh nomesh sc sm tcg, $(ALLOCS)) +endif + +all: allocs benchmarks_all +allocs: $(ALLOCS) +benchmarks_all: benchmarks $(BENCHMARKS_EXTERN) + +# TODO: Mac seems to report 'arm64' here +ifeq ($(shell uname -m), aarch64) +# gd uses SSE on x86, but ARC4 on ARM - and arc4 needs a fix +gd_ENV := ARC4RNG=1 +extern/gd/.built: extern/gd/.unpacked + sed -i_orig 's/getentropy(/_getentropy(/g' $(@D)/rng/arc4random.{c,h} + make -C $(@D) $(gd_ENV) -j$(PROCS) + touch $@ +endif + +.PHONY: all allocs benchmarks benchmarks_all benchmarks_big clean-archives + +benchmarks: bench/CMakeLists.txt bench/shbench/sh6bench-new.c bench/shbench/sh8bench-new.c $(PDFDOC) + cmake -B out/bench -S bench + cmake --build out/bench -j $(PROCS) + +PDF_URL=https://raw.githubusercontent.com/geekaaron/Resources/master/resources/Writing_a_Simple_Operating_System--from_Scratch.pdf +$(PDFDOC): + mkdir -p extern + wget --no-verbose -O $(PDFDOC).part $(PDF_URL) && mv -f $(PDFDOC).part $(PDFDOC) || { rm -f $(PDFDOC).part; false; } + +bench/shbench/sh6bench-new.c: bench/shbench/sh6bench.patch bench/shbench/sh6bench.c + dos2unix $< + patch -p1 -o $@ $(filter-out $<, $^) $< + +bench/shbench/sh8bench-new.c: bench/shbench/sh8bench.patch bench/shbench/SH8BENCH.C + dos2unix $< + patch -p1 -o $@ $(filter-out $<, $^) $< + +bench/shbench/sh6bench.c: bench/shbench/bench.zip + cd $(@D) && unzip -o $( $@ + +.SECONDEXPANSION: +extern/%/.unpacked: archives/%-$$(call label_of,$$*).tar.gz + mkdir -p $(@D) + tar -x --strip-components=1 --overwrite -f $< -C $(@D) $($*_TAR_FLAG) + echo "$($*_LABEL) $($*_VERSION)" > $@ + +clean-archives: + rm -f $(filter-out $(archives) $(clones),$(wildcard archives/*)) + +######################################################################## +# ALLOCS: nontrivial cases +######################################################################## +#dh: uses cmake +extern/dh/.configured: extern/dh/.unpacked + cmake -S $(@D) -B $(@D)/build -D BUILD_DIEHARDER=1 + touch $@ + +extern/dh/.built: extern/dh/.configured + cmake --build $(@D)/build -j $(PROCS) + touch $@ + +#hd: fix in Makefile. +extern/hd/.built: extern/hd/.unpacked + sed -i_orig 's/-arch arm64e//g' $(@D)/src/GNUmakefile + sed -i_orig 's/-arch arm64//g' $(@D)/src/GNUmakefile + patch -d $(@D) -p1 -N -r- < patches/hoard.patch + make -C $(@D) $(hd_ENV) -j$(PROCS) + touch $@ + +#hm/hml (hm light): built from the same source, differently configured +hm_ENV=CONFIG_NATIVE=true CONFIG_WERROR=false VARIANT=default +hml_ENV=CONFIG_NATIVE=true CONFIG_WERROR=false VARIANT=light +extern/hm/.built: extern/hm/.unpacked + make -C $(@D) $(hm_ENV) -j$(PROCS) + make -C $(@D) $(hml_ENV) -j$(PROCS) + touch $@ + +#je: needs configure +extern/je/.built: extern/je/config.status + make -C $(@D) -j$(PROCS) + touch $@ + +extern/je/config.status: extern/je/.unpacked + cd $(@D) && ./autogen.sh --enable-doc=no --enable-static=no --disable-stats + +# lp: partial checkout and some fixes +extern/lp/.built: extern/lp/.unpacked + cd $(@D)/Source/bmalloc/libpas && CC=clang CXX=clang++ LDFLAGS='-lpthread -latomic -pthread' bash ./build.sh -s cmake -v default -t pas_lib + touch $@ + +extern/lp/.unpacked: archives/lp-$(lp_LABEL).clone + rm -rf $(@D) + git clone --depth 1 --no-checkout --filter=blob:none $(lp_URL) $(@D) + printf '/*\n!/*/\n/Source/bmalloc/libpas/*\n' > $(@D)/.git/info/sparse-checkout + git -C $(@D) config core.sparseCheckout true + git -C $(@D) fetch --depth 1 origin $(lp_VERSION) + git -C $(@D) checkout --detach FETCH_HEAD + cd $(@D)/Source/bmalloc/libpas && sed -i $(ORIG) 's/extra_cmake_options=""/extra_cmake_options="-D_GNU_SOURCE=1"/' build.sh + cd $(@D)/Source/bmalloc/libpas && sed -i $(ORIG) 's/cmake --build $$build_dir --parallel/cmake --build $$build_dir --target pas_lib --parallel/' build.sh + echo "$(lp_LABEL) $(lp_VERSION)" > $@ + +# mi,mi2: cmake, and 3 different variants +extern/mi/.built extern/mi2/.built extern/mi3/.built: extern/%/.built: extern/%/.unpacked + cmake -S $(@D) -B $(@D)/out/release + cmake --build $(@D)/out/release -j$(PROCS) + cmake -S $(@D) -B $(@D)/out/debug -DMI_CHECK_FULL=ON + cmake --build $(@D)/out/debug -j$(PROCS) + cmake -S $(@D) -B $(@D)/out/secure -DMI_SECURE=ON + cmake --build $(@D)/out/secure -j$(PROCS) + touch $@ + +# nomesh: built from mesh's source +nomesh_ENV=DISABLE_MESHING=ON build +extern/nomesh/.built: extern/mesh/.unpacked + cp -r $( make +sc_ENV=BUILDTYPE=Release +extern/sc/.built: extern/sc/Makefile + make -C $(@D) $(sc_ENV) -j$(PROCS) + touch $@ + +extern/sc/Makefile: extern/sc/tools/gyp + cd $(@D) && tools/gyp --depth=. scalloc.gyp + +extern/sc/tools/gyp: extern/sc/.unpacked + cd extern/sc && tools/make_deps.sh + +#scudo: partial checkout, native clang, in a sub-directory +extern/scudo/.unpacked: archives/scudo-$(scudo_LABEL).clone + rm -rf $(@D) + git clone --depth 1 --no-checkout --filter=blob:none $(scudo_URL) $(@D) + printf '/*\n!/*/\n/compiler-rt/lib/scudo/standalone/*\n' > $(@D)/.git/info/sparse-checkout + git -C $(@D) config core.sparseCheckout true + git -C $(@D) fetch --depth 1 origin $(scudo_VERSION) + git -C $(@D) checkout --detach FETCH_HEAD + echo "$(scudo_LABEL) $(scudo_VERSION)" > $@ + +extern/scudo/.built: extern/scudo/.unpacked + cd $(@D)/compiler-rt/lib/scudo/standalone && clang++ -flto -fuse-ld=lld -fPIC -fno-exceptions $(CXXFLAGS) -fno-rtti -fvisibility=internal -O3 -I include -shared -o libscudo.$(EXTSO) *.cpp + touch $@ + +#sm: make, but a fix before +extern/sm/.built: extern/sm/.unpacked + sed -i "s/-Werror//" $(@D)/Makefile.include + make -C $(@D)/release -j$(PROCS) ../release/lib/libsupermalloc.so + touch $@ + +#sn: cmake+ninja, builds in sn/release +extern/sn/.built: extern/sn/release/build.ninja + cd $(@D)/release && ninja libsnmallocshim.$(EXTSO) libsnmallocshim-checks.$(EXTSO) + touch $@ + +extern/sn/release/build.ninja: extern/sn/.unpacked + env CXX=clang++ cmake -S $(@D)/.. -B $(@D) -G Ninja -DCMAKE_BUILD_TYPE=Release + +#tbb: cmake to configure +extern/tbb/.built: extern/tbb/.configured + make -C $(@D) -j$(PROCS) + touch $@ + +extern/tbb/.configured: extern/tbb/.unpacked + cd $(@D) && cmake -DCMAKE_BUILD_TYPE=Release -DTBB_BUILD=OFF -DTBB_TEST=OFF -DTBB_OUTPUT_DIR_BASE=bench -DCMAKE_POLICY_VERSION_MINIMUM=3.5 . + touch $@ + +#tc: autogen+configure +extern/tc/.built: extern/tc/Makefile + make -C $(@D) -j $(PROCS) + touch $@ + +extern/tc/Makefile: extern/tc/configure + cd $(@D) && CXXFLAGS="$(CXXFLAGS) -w -DNDEBUG -O2" ./configure --enable-minimal --disable-debugalloc + +extern/tc/configure: extern/tc/.unpacked + cd $(@D) && ./autogen.sh + +#tcg: bazel +extern/tcg/.built: extern/tcg/.unpacked + patch -d $(@D) -p1 -N -r- < patches/tcg.patch + cd $(@D) && bazel build -c opt tcmalloc //tcmalloc:libtcmalloc.so + touch $@ + +#s: rust workspace +extern/s/.built: extern/s/.unpacked + cd $(@D) && cargo build --release --package smalloc-ffi + touch $@ + +#yal: custom shell script +extern/yal/.built: extern/yal/.unpacked + cd $(@D) && ./build.sh -V + touch $@ + +######################################################################## +# benchmarks residing in ./extern # +######################################################################## +# lean: cmake +extern/lean/.built: extern/lean/.unpacked + patch -d $(@D) -p1 -N -r- < patches/lean.patch + mkdir -p $(@D)/out/release + env CC=gcc CXX="g++" cmake -S $(@D)/src -B $(@D)/out/release -DCUSTOM_ALLOCATORS=OFF -DLEAN_EXTRA_CXX_FLAGS="-w" -DCMAKE_POLICY_VERSION_MINIMUM=3.5 + make -C $(@D)/out/release -j$(PROCS) bin_lean + touch $@ + +# mathlib only needs to be fetched; the benchmark itself builds it via leanpkg +extern/mathlib/.built: extern/mathlib/.unpacked + touch $@ + +# lua only needs to be fetched, not more. +extern/lua/.built: extern/lua/.unpacked + touch $@ + +# linux only needs to be fetched, not more. +extern/linux/.built: extern/linux/.unpacked + touch $@ + +# rocksdb: musl defines neither _POSIX_C_SOURCE nor _XOPEN_SOURCE by default, +# which makes rocksdb allocate its cache shards with plain malloc +extern/rocksdb/.built: extern/rocksdb/.unpacked + patch -d $(@D) -p1 -N -r- < patches/rocksdb_cacheline_alloc.patch + make -C $(@D) $(rocksdb_ENV) -j$(PROCS) + touch $@ diff --git a/README.md b/README.md index 82a0fa1..00eee26 100644 --- a/README.md +++ b/README.md @@ -10,15 +10,8 @@ Collection of various benchmarks from the academic literature, together with automated scripts to pull specific versions of benchmark programs and allocators from Github and build them. -Due to the large variance in programs and allocators, the suite is currently -only developed for Unix-like systems, and specifically Ubuntu with `apt-get`, Fedora with `dnf`, -and macOS (for a limited set of allocators and benchmarks). The only system-installed allocator used is glibc's implementation that ships as part of Linux's libc. -All other allocators are downloaded and built as part of `build-bench-env.sh` -- -if you are looking to run these benchmarks on a different Linux distribution look at -the `setup_packages` function to see the packages required to build the full set of -allocators. - +All other allocators are downloaded and built with `make`. It is quite easy to add new benchmarks and allocator implementations -- please do so!. @@ -27,23 +20,80 @@ Enjoy, Daan - Note that all the code in the `bench` directory is not part of _mimalloc-bench_ as such, and all programs in the `bench` directory are governed under their own specific licenses and copyrights as detailed in their `README.md` (or `license.txt`) files. They are just included here for convenience. +# Dependencies +Some of the allocators and benchmarks need packages installed on the +system to be built and/or run. See the following collection for your +distribution: +
+ Ubuntu/Debian + +```bash +sudo apt-get install --no-install-recommends build-essential git gpg \ + g++ clang lld llvm-dev unzip dos2unix linuxinfo bc libgmp-dev wget \ + cmake python3 ruby cargo ninja-build libtool autoconf sed ghostscript \ + time curl automake libatomic1 libgflags-dev libsnappy-dev \ + zlib1g-dev libbz2-dev liblz4-dev libzstd-dev libreadline-dev \ + pkg-config gawk util-linux bsdextrautils bazel-bootstrap flex bison libelf-dev +``` +
+ +
+ Fedora + +```bash +sudo dnf --nodocs install gcc-c++ clang lld llvm-devel unzip dos2unix bc \ + gmp-devel wget gawk cmake python3 ruby ninja-build libtool autoconf \ + git patch time sed ghostscript libatomic libstdc++ which gflags-devel \ + xz readline-devel snappy-devel rust dnf-plugins-core flex bison \ + elfutils-libelf-devel +sudo dnf copr -y enable ohadm/bazel +sudo dnf --nodocs install bazel8 +``` +
+ +
+ Alpine + +```bash +sudo apk add clang lld unzip dos2unix bc gmp-dev wget cmake python3 ruby \ + automake gawk samurai libtool git build-base linux-headers autoconf \ + util-linux sed ghostscript libatomic gflags-dev readline-dev snappy-dev cargo \ + flex bison elfutils-dev +echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" | sudo tee -a /etc/apk/repositories +sudo apk add -q bazel@testing +``` +
+ +
+ ArchLinux + +```bash +sudo pacman -S dos2unix wget cmake ninja automake libtool time gmp sed \ + ghostscript bazelisk gflags snappy python-six ruby flex bison libelf +``` +
+ +
+ Mac OS + +```bash +brew install dos2unix wget cmake ninja automake libtool gnu-time gmp \ + mpir gnu-sed ghostscript bazelisk gflags snappy +``` +
# Benchmarking -The `build-bench-env.sh` script with the `all` argument will automatically pull -all needed benchmarks and allocators and build them in the `extern` directory: +`make all` will automatically pull all needed benchmarks and allocators +and build them in the `extern` directory: ``` -~/dev/mimalloc-bench> ./build-bench-env.sh all +~/dev/mimalloc-bench> make all ``` -It starts installing packages and you will need to enter the sudo password. -All other programs are build in the `mimalloc-bench/extern` directory. -Use `./build-bench-env.sh -h` to see all options. If everything succeeded, you can run the full benchmark suite (from `out/bench`) as: @@ -81,11 +131,23 @@ sudo aa-teardown GitHub CI runners have this profile, so the CI workflow unloads the host profiles before building. +**`sh6bench` reports "Out of memory" for some allocators although the machine +has plenty of memory?** +Some allocators (hardened_malloc `hm` for example) map guard pages around their +allocations, so every live allocation costs at least one extra kernel mapping, +and `sh6bench` keeps tens of thousands of them alive at once: with 16 threads it +measures over 140000 mappings, more than the default `vm.max_map_count` of +65530. Once the limit is reached, `mprotect` fails and `malloc` returns null. +Raise the limit: +``` +sudo sysctl -w vm.max_map_count=1048576 +``` + ## Current Allocators Supported allocators are as follow, see -[build-bench-env.sh](https://github.com/daanx/mimalloc-bench/blob/master/build-bench-env.sh) -for the versions: +[VERSIONS](VERSIONS) +for the pinned versions: - **dieharder**: The [_DieHarder_](https://github.com/emeryberger/DieHard) allocator is an error-resistant memory allocator for Windows, Linux, and Mac diff --git a/VERSIONS b/VERSIONS new file mode 100644 index 0000000..960088b --- /dev/null +++ b/VERSIONS @@ -0,0 +1,36 @@ +dh: 4467f2b0, 4467f2b0bacf2e2a4d3a8eb7b89972a4d74ee290, https://github.com/emeryberger/DieHard +ff: 2f24ecf7, 2f24ecf728886dc0ea29b5f2adab2df9c881befa, https://github.com/bwickman97/ffmalloc +fg: bfdf6d9a, bfdf6d9a5b25c3f8f974c6a2ac7bb286e5c2b296, https://github.com/UTSASRG/FreeGuard +gd: 9e85978a, 9e85978aa2e883010cb5d0c4ae1ae7fe7b8fbe6c, https://github.com/UTSASRG/Guarder +hd: 6577c22b, 6577c22b1768656be5e611da67c5bebe65f33c88, https://github.com/emeryberger/Hoard +hm: 11, 995ce07d4559460b1060991ada7bca1482e4271b, https://github.com/GrapheneOS/hardened_malloc +iso: 1.2.5, 2670d5f5e41220e126569e78cb4e3e0379d6cb08, https://github.com/struct/isoalloc +je: 5.4.0, 7a34f18502e7b222724097cdcd499b437d189acc, https://github.com/jemalloc/jemalloc +kp: v1.1.0, a26213ab68daa09ed3ab94070e96b0eda7008e85, https://github.com/northriv/kamepoolalloc +lean: 21d264a6, 21d264a66d53b0a910178ae7d9529cb5886a39b6, https://github.com/leanprover-community/lean +lf: 915f51b2, 915f51b282c5a31b18fb9b96ef19da410b00a421, https://github.com/Begun/lockfree-malloc +linux: 6.6.105, fe9731e100041bb2cc186717bde3e05ca175623b, https://github.com/torvalds/linux +lp: 38fd6ffa, 38fd6ffa2cc41a0551addec71174c63f7c40648f, https://github.com/WebKit/WebKit +lt: d31b0c92, d31b0c92d37bb0bf6f0c28a6e8dc2b9978bc8ef3, https://github.com/r-lyeh-archived/ltalloc +lua: v5.4.7, 1ab3208a1fceb12fca8f24ba57d6e13c5bff15e3, https://github.com/lua/lua +mathlib: release_812, 9f55d0d4363ae59948c33864cbc52e0b12e0e8ce, https://github.com/leanprover-community/mathlib3 +mesh: 1f298380, 1f298380f4d49ed8852c2ab23d461ef0bd835c92, https://github.com/plasma-umass/mesh +mi3: v3.6.0, b18ab4eef383f655e760881b02eff8af02800879, https://github.com/microsoft/mimalloc +mi2: v2.1.2, 43ce4bd7fd34bcc730c1c7471c99995597415488, https://github.com/microsoft/mimalloc +mi: v1.8.2, b66e3214d8a104669c2ec05ae91ebc26a8f5ab78, https://github.com/microsoft/mimalloc +mng: 2ed58817, 2ed58817cca5bc055974e5a0e43c280d106e696b, https://github.com/richfelker/mallocng-draft +pa: e6c10be6, e6c10be65e0e916f4befb695779483a44e4a8439, https://github.com/1c3t3a/partition_alloc_builder +redis: 6.2.7, e6f67092f8d4d81761a60c46011d1ff1dc3c2628, https://github.com/redis/redis +rmalloc: 3498679f, 3498679f5240c11a9d88b9aa4ef45e79ef5e6eaa, https://github.com/newell-romario/rmalloc +rocksdb: 11.1.2, 3b446089141659fad25328c5ea3e7ed283df46e4, https://github.com/facebook/rocksdb +rp: 2.0.1, beef233c176b235587c0145f765e4316e5ca60d1, https://github.com/mjansson/rpmalloc +sc: 9ef491c3, 9ef491c391f4d78c23990142ad8b51fa1c1879b8, https://github.com/cksystemsgroup/scalloc +scudo: 0e42735b, 0e42735b0df2071a34bdee283ec2387c3c7262c3, https://github.com/llvm/llvm-project +sg: 6d7d065a, 6d7d065ac9ce7203250aa44b4b333b58ca93c803, https://github.com/ssrg-vt/SlimGuard +sm: 709663fb, 709663fb81ba091b0a78058869a644a272f4163d, https://github.com/kuszmaul/SuperMalloc +sn: 0.7.6, f126f1c94d624976d57568d2c6c8a80bc66549bc, https://github.com/Microsoft/snmalloc +s: v7.6.0, 4632ddc2930b35eca216dc71f5b75c0321a5fe93, https://github.com/zooko/smalloc +tbb: v2023.1.0, 3046c8b0c29df995980003ea24f4d78c80ec0c8d, https://github.com/oneapi-src/oneTBB +tcg: 81f4e44f, 81f4e44f23f2936303f9404fee7315119b9df623, https://github.com/google/tcmalloc +tc: gperftools-2.18, 6ed73507dd3970a123e267a50b3ee73392e3b053, https://github.com/gperftools/gperftools +yal: d0776466, d077646672cf5179e4fe120fcd8b28e6309a517b, https://github.com/jorisgeer/yalloc diff --git a/bench.sh b/bench.sh index 8b9bc5c..451b999 100755 --- a/bench.sh +++ b/bench.sh @@ -23,14 +23,6 @@ tests_run="" tests_exclude="" readonly tests_exclude_macos="sh6bench sh8bench redis" -# -------------------------------------------------------------------- -# benchmark versions -# -------------------------------------------------------------------- - -readonly version_redis=6.2.7 -readonly version_rocksdb=10.10.1 -readonly version_linux=6.6.105 - # -------------------------------------------------------------------- # Environment # -------------------------------------------------------------------- @@ -72,7 +64,7 @@ esac # -------------------------------------------------------------------- readonly curdir=`pwd` -if ! test -f ../../build-bench-env.sh; then +if ! test -f ../../bench.sh; then echo "error: you must run this script from the 'out/bench' directory!" exit 1 fi @@ -101,7 +93,7 @@ readonly lib_tbb="$localdevdir/tbb/bench_release/libtbbmalloc_proxy$extso" readonly lib_tbb_dir="$(dirname $lib_tbb)" -alloc_lib_add "dh" "$localdevdir/dh/src/build/libdieharder$extso" +alloc_lib_add "dh" "$localdevdir/dh/build/libdieharder$extso" alloc_lib_add "ff" "$localdevdir/ff/libffmallocnpmt$extso" alloc_lib_add "fg" "$localdevdir/fg/libfreeguard$extso" alloc_lib_add "gd" "$localdevdir/gd/libguarder$extso" @@ -113,9 +105,9 @@ alloc_lib_add "je" "$localdevdir/je/lib/libjemalloc$extso" alloc_lib_add "lf" "$localdevdir/lf/liblite-malloc-shared$extso" alloc_lib_add "lp" "$localdevdir/lp/Source/bmalloc/libpas/build-cmake-default/Release/libpas_lib$extso" alloc_lib_add "lt" "$localdevdir/lt/gnu.make.lib/libltalloc$extso" -alloc_lib_add "mesh" "$localdevdir/mesh/build/lib/libmesh$extso" +alloc_lib_add "mesh" "$localdevdir/mesh/bazel-bin/src/libmesh$extso" alloc_lib_add "mng" "$localdevdir/mng/libmallocng$extso" -alloc_lib_add "nomesh" "$localdevdir/nomesh/build/lib/libmesh$extso" +alloc_lib_add "nomesh" "$localdevdir/nomesh/bazel-bin/src/libmesh$extso" alloc_lib_add "pa" "$localdevdir/pa/partition_alloc_builder/out/Default/libpalib$extso" alloc_lib_add "kp" "$localdevdir/kp/out/libkamepoolalloc$extso" alloc_lib_add "rp" "$lib_rp" @@ -172,10 +164,10 @@ fi readonly luadir="$localdevdir/lua" readonly leandir="$localdevdir/lean" readonly leanmldir="$leandir/../mathlib" -readonly redis_dir="$localdevdir/redis-$version_redis/src" +readonly redis_dir="$localdevdir/redis/src" readonly pdfdoc="$localdevdir/large.pdf" -readonly rocksdb_dir="$localdevdir/rocksdb-$version_rocksdb" -readonly linux_dir="$localdevdir/linux-$version_linux" +readonly rocksdb_dir="$localdevdir/rocksdb" +readonly linux_dir="$localdevdir/linux" readonly spec_dir="$localdevdir/../../spec2017" readonly spec_base="base" diff --git a/build-bench-env.sh b/build-bench-env.sh deleted file mode 100755 index c8ec595..0000000 --- a/build-bench-env.sh +++ /dev/null @@ -1,980 +0,0 @@ -#!/bin/bash -# Copyright 2018-2024, Microsoft Research, Daan Leijen, Julien Voisin, Matthew Parkinson - -set -eo pipefail - -CFLAGS='-march=native' -CXXFLAGS='-march=native' - -procs=8 -extso=".so" -case "$OSTYPE" in - darwin*) - export HOMEBREW_NO_EMOJI=1 - darwin="1" - extso=".dylib" - procs=`sysctl -n hw.physicalcpu`;; - *) - darwin="" - if command -v nproc > /dev/null; then - procs=`nproc` - fi;; -esac - -SUDO=sudo -if [ "$EUID" -eq 0 ]; then - echo "[*] $0 is running as root, avoid doing this if possible." - SUDO="" -fi - -SHA256SUM_CMD="sha256sum" -if test "$darwin" = "1"; then - SHA256SUM_CMD="shasum -a 256" -fi - -curdir=`pwd` -rebuild=0 -all=0 - -# allocator versions -readonly version_dh=master -readonly version_ff=master # ~unmaintained since 2021 -readonly version_fg=master # ~unmaintained since 2018 -readonly version_gd=master # ~unmaintained since 2021 -readonly version_hd=6577c22b # HEAD as of 2025-07-18, no release since 2019 -readonly version_hm=11 -readonly version_iso=1.2.5 -readonly version_je=5.4.0 -readonly version_lf=master # ~unmaintained since 2018 -readonly version_lp=main -readonly version_kp=v1.1.0 -readonly version_lt=master # ~unmaintained since 2019 -readonly version_mesh=master # ~unmaintained since 2021 -readonly version_mi=v1.8.2 -readonly version_mi2=v2.1.2 -readonly version_mi3=v3.6.0 -readonly version_mng=master # ~unmaintained -readonly version_nomesh=$version_mesh -readonly version_pa=main -readonly version_rp=2.0.1 -readonly version_sc=master # unmaintained since 2016 -readonly version_scudo=main -readonly version_sg=master # ~unmaintained since 2021 -readonly version_sm=master # ~unmaintained since 2017 -readonly version_sn=0.7.6 -readonly version_s=v7.6.0 -readonly version_tbb=v2023.1.0 -readonly version_tc=gperftools-2.18 -readonly version_tcg=81f4e44f23f2936303f9404fee7315119b9df623 # 2026-02-23 -readonly version_yal=main -readonly version_rmalloc=master - -# benchmark versions -readonly version_redis=6.2.7 -readonly version_lean=21d264a66d53b0a910178ae7d9529cb5886a39b6 # build fix for recent compilers -readonly version_mathlib=release_812 -readonly version_rocksdb=10.10.1 -readonly version_lua=v5.4.7 -readonly version_linux=6.6.105 -readonly version_bazel=8.8.0 -readonly version_rust=1.87.0 - -# HTTP-downloaded files checksums -readonly sha256sum_sh6bench="506354d66b9eebef105d757e055bc55e8d4aea1e7b51faab3da35b0466c923a1" -readonly sha256sum_sh8bench="12a8e75248c9dcbfee28245c12bc937a16ef56ec9cbfab88d0e348271667726f" - -# allocators -setup_dh=0 -setup_ff=0 -setup_fg=0 -setup_gd=0 -setup_hd=0 -setup_hm=0 -setup_iso=0 -setup_je=0 -setup_lf=0 -setup_lp=0 -setup_lt=0 -setup_mesh=0 -setup_mi=0 -setup_mi2=0 -setup_mi3=0 -setup_mng=0 -setup_nomesh=0 -setup_pa=0 -setup_kp=0 -setup_rp=0 -setup_sc=0 -setup_scudo=0 -setup_sg=0 -setup_sm=0 -setup_sn=0 -setup_s=0 -setup_tbb=0 -setup_tc=0 -setup_tcg=0 -setup_yal=0 -setup_rmalloc=0 - -# bigger benchmarks -setup_bench=0 -setup_lean=0 -setup_redis=0 -setup_rocksdb=0 -setup_linux=0 - -# various -setup_packages=0 - - -# Parse command-line arguments -while : ; do - flag="$1" - case "$flag" in - *=*) flag_arg="${flag#*=}";; - no-*) flag_arg="0" - flag="${flag#no-}";; - none) flag_arg="0" ;; - *) flag_arg="1" ;; - esac - # echo "option: $flag, arg: $flag_arg" - case "$flag" in - "") break;; - all|none) - all=$flag_arg - setup_kp=$flag_arg - setup_dh=$flag_arg - setup_ff=$flag_arg - setup_fg=$flag_arg - setup_gd=$flag_arg - setup_hd=$flag_arg - setup_iso=$flag_arg - setup_je=$flag_arg - setup_lp=$flag_arg - setup_mi=$flag_arg - setup_mi2=$flag_arg - setup_mi3=$flag_arg - setup_pa=$flag_arg - setup_sn=$flag_arg - setup_s=$flag_arg - setup_sg=$flag_arg - setup_tbb=$flag_arg - setup_tc=$flag_arg - setup_yal=$flag_arg - setup_rmalloc=$flag_arg - if [ -z "$darwin" ]; then - setup_tcg=$flag_arg # lacking 'malloc.h' - setup_dh=$flag_arg - setup_fg=$flag_arg - setup_lf=$flag_arg - setup_lt=$flag_arg # GNU only - setup_mng=$flag_arg # lacking getentropy() - setup_hm=$flag_arg # lacking - setup_mesh=$flag_arg - setup_rp=$flag_arg - setup_scudo=$flag_arg # lacking - setup_sm=$flag_arg # ../src/supermalloc.h:10:31: error: expected function body after function declarator + error: use of undeclared identifier 'MADV_HUGEPAGE' - else - if ! [ `uname -m` = "x86_64" ]; then - setup_dh=$flag_arg # does not compile on macos x64 - fi - fi - # only run Mesh's 'nomesh' configuration if asked - # setup_nomesh=$flag_arg - # bigger benchmarks - setup_lean=$flag_arg - setup_redis=$flag_arg - setup_rocksdb=$flag_arg - setup_linux=$flag_arg - setup_bench=$flag_arg - setup_packages=$flag_arg - ;; - bench) - setup_bench=$flag_arg;; - rmalloc) - setup_rmalloc=$flag_arg;; - ff) - setup_ff=$flag_arg;; - fg) - setup_fg=$flag_arg;; - dh) - setup_dh=$flag_arg;; - gd) - setup_gd=$flag_arg;; - hd) - setup_hd=$flag_arg;; - hm) - setup_hm=$flag_arg;; - iso) - setup_iso=$flag_arg;; - je) - setup_je=$flag_arg;; - lf) - setup_lf=$flag_arg;; - lp) - setup_lp=$flag_arg;; - lt) - setup_lt=$flag_arg;; - lean) - setup_lean=$flag_arg;; - mng) - setup_mng=$flag_arg;; - mesh) - setup_mesh=$flag_arg;; - mi) - setup_mi=$flag_arg;; - mi2) - setup_mi2=$flag_arg;; - mi3) - setup_mi3=$flag_arg;; - nomesh) - setup_nomesh=$flag_arg;; - pa) - setup_pa=$flag_arg;; - packages) - setup_packages=$flag_arg;; - redis) - setup_redis=$flag_arg;; - rocksdb) - setup_rocksdb=$flag_arg;; - linux) - setup_linux=$flag_arg;; - kp) - setup_kp=$flag_arg;; - rp) - setup_rp=$flag_arg;; - sc) - setup_sc=$flag_arg;; - scudo) - setup_scudo=$flag_arg;; - sg) - setup_sg=$flag_arg;; - sm) - setup_sm=$flag_arg;; - sn) - setup_sn=$flag_arg;; - s) - setup_s=$flag_arg;; - tbb) - setup_tbb=$flag_arg;; - tc) - setup_tc=$flag_arg;; - tcg) - setup_tcg=$flag_arg;; - yal) - setup_yal=$flag_arg;; - - -r|--rebuild) - rebuild=1;; - -j=*|--procs=*) - procs=$flag_arg;; - -h|--help|-\?|help|\?) - echo "./build-bench-env [options]" - echo "" - echo " all setup and build (almost) everything" - echo "" - echo " --procs= number of processors (=$procs)" - echo " --rebuild force re-clone and re-build for given tools" - echo "" - echo " dh setup dieharder ($version_dh)" - echo " ff setup ffmalloc ($version_ff)" - echo " fg setup freeguard ($version_fg)" - echo " gd setup guarder ($version_gd)" - echo " hd setup hoard ($version_hd)" - echo " hm setup hardened_malloc ($version_hm)" - echo " iso setup isoalloc ($version_iso)" - echo " je setup jemalloc ($version_je)" - echo " lf setup lockfree-malloc ($version_lf)" - echo " lp setup libpas ($version_lp)" - echo " lt setup ltmalloc ($version_lt)" - echo " mesh setup mesh allocator ($version_mesh)" - echo " mi setup mimalloc ($version_mi)" - echo " mi2 setup mimalloc ($version_mi2)" - echo " mi3 setup mimalloc ($version_mi3)" - echo " mng setup mallocng ($version_mng)" - echo " nomesh setup mesh allocator w/o meshing ($version_mesh)" - echo " pa setup PartitionAlloc ($version_pa)" - echo " kp setup kamepoolalloc ($version_kp)" - echo " rp setup rpmalloc ($version_rp)" - echo " sc setup scalloc ($version_sc)" - echo " scudo setup scudo ($version_scudo)" - echo " sg setup slimguard ($version_sg)" - echo " sm setup supermalloc ($version_sm)" - echo " sn setup snmalloc ($version_sn)" - echo " s setup smalloc ($version_s)" - echo " tbb setup Intel TBB malloc ($version_tbb)" - echo " tc setup tcmalloc ($version_tc)" - echo " tcg setup Google's tcmalloc ($version_tcg)" - echo " yal setup yalloc ($version_yal)" - echo " rmalloc setup rmalloc($version_rmalloc)" - echo "" - echo " bench build all local benchmarks" - echo " lean setup lean 3 benchmark" - echo " packages setup required packages" - echo " redis setup redis benchmark" - echo " rocksdb setup rocksdb benchmark" - echo " linux setup linux benchmark" - echo "" - echo "Prefix an option with 'no-' to disable an option" - exit 0;; - *) echo "warning: unknown option \"$1\"." 1>&2 - esac - shift -done - -if test -f ./build-bench-env.sh; then - echo "" - echo "use '-h' to see all options" - echo "use 'all' to build all allocators" - echo "" - echo "building with $procs threads" - echo "--------------------------------------------" - echo "" -else - echo "error: must run from the toplevel mimalloc-bench directory!" - exit 1 -fi - -mkdir -p extern -readonly devdir="$curdir/extern" - -function phase { - cd "$curdir" - echo - echo - echo "--------------------------------------------" - echo "$1" - echo "--------------------------------------------" - echo -} - -function write_version { # name, git-tag, repo - commit=$(git log -n1 --format=format:"%h") - echo "$1: $2, $commit, $3" > "$devdir/version_$1.txt" -} - -function partial_checkout { # name, git-tag, git repo, directory to download - phase "build $1: version $2" - pushd $devdir - if test "$rebuild" = "1"; then - rm -rf "$1" - fi - if test -d "$1"; then - echo "$devdir/$1 already exists; no need to git clone" - cd "$1" - else - mkdir "$1" - cd "$1" - git init - git remote add origin $3 - git config extensions.partialClone origin - git sparse-checkout set $4 - fi - git fetch --depth=1 --filter=blob:none origin $2 - git checkout $2 - git reset origin/$2 --hard - write_version $1 $2 $3 -} - -function checkout { # name, git-tag, git repo, options - phase "build $1: version $2" - pushd $devdir - if test "$rebuild" = "1"; then - rm -rf "$1" - fi - if test -d "$1"; then - echo "$devdir/$1 already exists; no need to git clone" - else - git clone $4 $3 $1 - fi - cd "$1" - git checkout $2 - write_version $1 $2 $3 -} - -function check_checksum { # name, sha256sum - if (echo "$2 $1" | $SHA256SUM_CMD --check --status); then - echo "$1 has correct checksum" - else - echo "$1 has wrong checksum" - echo "$2 was expected" - $SHA256SUM_CMD $1 - fi -} - -function aptinstall { - echo "" - echo "> $SUDO apt install $1" - echo "" - $SUDO apt install -y --no-install-recommends $1 -} - -function dnfinstall { - echo "" - echo "> $SUDO dnf -y --quiet --nodocs install $1" - echo "" - $SUDO dnf -y --quiet --nodocs install $1 -} - -function apkinstall { - echo "" - echo "> apk add -q $1" - echo "" - apk add -q $1 -} - -function brewinstall { - echo "" - echo "> brew install $1" - echo "" - brew install $1 -} - -function aptinstallbazel { - echo "" - echo "> installing bazel" - echo "" - aptinstall apt-transport-https curl gnupg - curl -fsSL https://releases.bazel.build/bazel-release.pub.gpg | gpg --dearmor > bazel-archive-keyring.gpg - $SUDO mv bazel-archive-keyring.gpg /usr/share/keyrings - echo "deb [arch=amd64 signed-by=/usr/share/keyrings/bazel-archive-keyring.gpg] https://storage.googleapis.com/bazel-apt stable jdk1.8" | $SUDO tee /etc/apt/sources.list.d/bazel.list - $SUDO apt update -qq - aptinstall bazel-$version_bazel - $SUDO ln -sf /usr/bin/bazel-$version_bazel /usr/bin/bazel -} - -function dnfinstallbazel { - echo "" - echo "> installing bazelisk" - echo "" - dnfinstall bazelisk -} - -if test "$all" = "1"; then - if test "$rebuild" = "1"; then - phase "clean $devdir for a full rebuild" - pushd "$devdir" - cd .. - rm -rf "extern/*" - popd - fi -fi - - -if test "$setup_packages" = "1"; then - phase "install packages" - if grep -q 'ID=fedora' /etc/os-release 2>/dev/null; then - # no 'apt update' equivalent needed on Fedora - dnfinstall "gcc-c++ clang lld llvm-devel unzip dos2unix bc gmp-devel wget gawk \ - cmake python3 ruby cargo ninja-build libtool autoconf git patch time sed \ - ghostscript libatomic libstdc++ libstdc++-static which gflags-devel xz readline-devel snappy-devel \ - flex bison elfutils-libelf-devel" - dnfinstallbazel - elif grep -q -e 'ID=debian' -e 'ID=ubuntu' /etc/os-release 2>/dev/null; then - echo "updating package database... ($SUDO apt update)" - $SUDO apt update -qq - aptinstall "build-essential git gpg g++ clang lld llvm-dev unzip dos2unix linuxinfo bc libgmp-dev wget \ - cmake python3 ruby ninja-build libtool autoconf sed ghostscript time \ - curl automake libatomic1 libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev \ - liblz4-dev libzstd-dev libreadline-dev pkg-config gawk util-linux \ - flex bison libelf-dev" - curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain $version_rust - aptinstallbazel - elif grep -q -e 'ID=alpine' /etc/os-release 2>/dev/null; then - echo "@testing http://nl.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories - apk update - apkinstall "clang lld unzip dos2unix bc gmp-dev wget cmake python3 ruby automake gawk \ - samurai libtool git cargo build-base linux-headers autoconf util-linux sed \ - ghostscript libatomic gflags-dev readline-dev snappy-dev \ - flex bison elfutils-dev" - apkinstall "bazel@testing" - elif brew --version 2> /dev/null >/dev/null; then - brewinstall "dos2unix wget cmake ninja automake libtool gnu-time gmp mpir gnu-sed \ - ghostscript bazelisk gflags snappy rust" - elif grep -q 'Arch Linux' /etc/os-release; then - sudo pacman -S dos2unix wget cmake ninja automake libtool time gmp sed ghostscript bazelisk gflags snappy rust ruby flex bison libelf - fi -fi - -if test "$setup_rmalloc" = "1"; then - checkout rmalloc $version_rmalloc https://github.com/newell-romario/rmalloc - cmake --preset linux-release - cmake --build --preset linux-release - popd -fi - -if test "$setup_hm" = "1"; then - checkout hm $version_hm https://github.com/GrapheneOS/hardened_malloc - if grep -q 'std::__throw_bad_alloc' new.cc; then - sed -i '/^#include $/d' new.cc - sed -i 's/std::__throw_bad_alloc();/throw std::bad_alloc();/g' new.cc - ! grep -q 'std::__throw_bad_alloc' new.cc - fi - make CONFIG_NATIVE=true CONFIG_WERROR=false VARIANT=light -j $procs - make CONFIG_NATIVE=true CONFIG_WERROR=false VARIANT=default -j $procs - popd -fi - -if test "$setup_gd" = "1"; then - checkout gd $version_gd https://github.com/UTSASRG/Guarder - make -j $procs - popd -fi - -if test "$setup_iso" = "1"; then - checkout iso $version_iso https://github.com/struct/isoalloc - make library -j $procs - popd -fi - -if test "$setup_lf" = "1"; then - checkout lf $version_lf https://github.com/Begun/lockfree-malloc - make -j $procs liblite-malloc-shared.so - popd -fi - -if test "$setup_ff" = "1"; then - checkout ff $version_ff https://github.com/bwickman97/ffmalloc - make -j $procs - popd -fi - -if test "$setup_mng" = "1"; then - checkout mng $version_mng https://github.com/richfelker/mallocng-draft - make -j $procs - popd -fi - -if test "$setup_scudo" = "1"; then - partial_checkout scudo $version_scudo https://github.com/llvm/llvm-project "compiler-rt/lib/scudo/standalone" - cd "compiler-rt/lib/scudo/standalone" - # TODO: make the next line prettier instead of hardcoding everything. - clang++ -flto -fuse-ld=lld -fPIC -std=c++17 -fno-exceptions $CXXFLAGS -fno-rtti -fvisibility=internal -msse4.2 -O3 -I include -shared -o libscudo$extso *.cpp -pthread - cd - - popd -fi - -if test "$setup_fg" = "1"; then - checkout "fg" $version_fg https://github.com/UTSASRG/FreeGuard - make -j $procs SSE2RNG=1 - popd -fi - -if test "$setup_lp" = "1"; then - partial_checkout lp $version_lp https://github.com/WebKit/WebKit "Source/bmalloc/libpas" - cd "Source/bmalloc/libpas" - ORIG="" - if test "$darwin" = "1"; then - ORIG="_orig" - fi - sed -i $ORIG '/Werror/d' CMakeLists.txt - # Fix compilation with recent compilers - # (at least clang16 that enforces -Wimplicit-function-declaration) - sed -i $ORIG 's/extra_cmake_options=""/extra_cmake_options="-D_GNU_SOURCE=1"/' build.sh - # Remove once/if https://github.com/WebKit/WebKit/pull/1219 is merged - sed -i $ORIG 's/cmake --build $build_dir --parallel/cmake --build $build_dir --target pas_lib --parallel/' build.sh - if test "$darwin" = "1"; then - ./build.sh -s cmake -v default -t pas_lib - else - CC=clang CXX=clang++ LDFLAGS='-lpthread -latomic -pthread' bash ./build.sh -s cmake -v default -t pas_lib - fi - cd - - popd -fi - -if test "$setup_lt" = "1"; then - checkout lt $version_lt https://github.com/r-lyeh-archived/ltalloc - make -j $procs -C gnu.make.lib - popd -fi - -if test "$setup_pa" = "1"; then - checkout pa $version_pa https://github.com/1c3t3a/partition_alloc_builder.git - - # Setup depot_tools for building - if test -d depot_tools; then - echo "depot_tools alrady exist, no cloning" - else - git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git --depth=1 - fi - export PATH="$PATH:$PWD/depot_tools" - - # Fetch sources - this relies on a standalone build of PA - gclient config https://github.com/1c3t3a/partition_alloc_builder.git - gclient sync - cd partition_alloc_builder - - gn gen out/Default - autoninja -C out/Default - popd -fi - -if test "$setup_sg" = "1"; then - checkout sg $version_sg https://github.com/ssrg-vt/SlimGuard - make -j $procs - popd -fi - -if test "$setup_dh" = "1"; then - checkout dh $version_dh https://github.com/emeryberger/DieHard - # remove all the historical useless junk - rm -rf ./benchmarks/ ./src/archipelago/ ./src/build/ ./src/exterminator/ ./src/local/ ./src/original-diehard/ ./src/replicated/ ./docs - cd src - cmake -S . -B build - cmake --build build -j `nproc` - cd ../.. - popd -fi - -if test "$setup_tbb" = "1"; then - checkout tbb $version_tbb https://github.com/oneapi-src/oneTBB - cmake -DCMAKE_BUILD_TYPE=Release -DTBB_BUILD=OFF -DTBB_TEST=OFF -DTBB_OUTPUT_DIR_BASE=bench . - make -j $procs - popd -fi - -if test "$setup_tc" = "1"; then - checkout tc $version_tc https://github.com/gperftools/gperftools - if test -f configure; then - echo "already configured" - else - ./autogen.sh - CXXFLAGS="$CXXFLAGS -w -DNDEBUG -O2" ./configure --enable-minimal --disable-debugalloc - fi - make -j $procs # ends with error on benchmark, but thats ok. - #echo "" - #echo "(note: the error 'Makefile:3912: recipe for target 'malloc_bench' failed' is expected)" - popd -fi - -if test "$setup_tcg" = "1"; then - checkout tcg $version_tcg https://github.com/google/tcmalloc - if command -v bazelisk > /dev/null; then - USE_BAZEL_VERSION=$version_bazel bazelisk build -c opt tcmalloc - else - bazel build -c opt tcmalloc - fi - popd -fi - -if test "$setup_hd" = "1"; then - checkout hd $version_hd https://github.com/emeryberger/Hoard - cd src - if [ "`uname -m -s`" = "Darwin x86_64" ] ; then - sed -i_orig 's/-arch arm64/ /g' GNUmakefile # fix the makefile - fi - make -j $procs - popd -fi - -if test "$setup_je" = "1"; then - checkout je $version_je https://github.com/jemalloc/jemalloc - if grep -q 'std::__throw_bad_alloc' src/jemalloc_cpp.cpp; then - sed -i 's/std::__throw_bad_alloc();/throw std::bad_alloc();/g' src/jemalloc_cpp.cpp - ! grep -q 'std::__throw_bad_alloc' src/jemalloc_cpp.cpp - fi - if test -f config.status; then - echo "$devdir/jemalloc is already configured; no need to reconfigure" - else - ./autogen.sh --enable-doc=no --enable-static=no --disable-stats - fi - make -j $procs - [ "$CI" ] && rm -rf ./src/*.o # jemalloc has like ~100MiB of object files - [ "$CI" ] && rm -rf ./lib/*.a # jemalloc produces 80MiB of static files - popd -fi - -if test "$setup_kp" = "1"; then - checkout kp $version_kp https://github.com/northriv/kamepoolalloc - cmake -B out -DCMAKE_BUILD_TYPE=Release - cmake --build out --parallel $procs - popd -fi - -if test "$setup_rp" = "1"; then - checkout rp $version_rp https://github.com/mjansson/rpmalloc - if test -f build.ninja; then - echo "$devdir/rpmalloc is already configured; no need to reconfigure" - else - python3 configure.py - fi - # fix build using clang-16 - # see https://github.com/mjansson/rpmalloc/issues/316 - sed -i 's/-Werror//' build.ninja - ninja - popd -fi - -if test "$setup_sn" = "1"; then - checkout sn $version_sn https://github.com/Microsoft/snmalloc - if test -f release/build.ninja; then - echo "$devdir/snmalloc is already configured; no need to reconfigure" - else - mkdir -p release - cd release - # CXX11_DESTRUCTORS is needed as broken on Alpine without, should be fixed in the future upstrem. - env CXX=clang++ cmake -G Ninja .. -DCMAKE_BUILD_TYPE=Release -DSNMALLOC_CLEANUP=CXX11_DESTRUCTORS - cd .. - fi - cd release - ninja libsnmallocshim$extso libsnmallocshim-checks$extso - popd -fi - -if test "$setup_s" = "1"; then - checkout s $version_s https://github.com/zooko/smalloc - cargo_cmd=cargo - if test -x "$HOME/.cargo/bin/cargo"; then - cargo_cmd="$HOME/.cargo/bin/cargo" - fi - "$cargo_cmd" build --release --package smalloc-ffi - popd -fi - -if test "$setup_sm" = "1"; then - checkout sm $version_sm https://github.com/kuszmaul/SuperMalloc - rm -rf ./doc ./paper "./short-talk" - sed -i "s/-Werror//" Makefile.include - cd release - make -j $procs - popd -fi - -if test "$setup_mesh" = "1"; then - checkout mesh $version_mesh https://github.com/plasma-umass/mesh - cmake . - make # https://github.com/plasma-umass/Mesh/issues/96 - popd -fi - -if test "$setup_nomesh" = "1"; then - checkout nomesh $version_nomesh https://github.com/plasma-umass/mesh - cmake . -DDISABLE_MESHING=ON - make # https://github.com/plasma-umass/Mesh/issues/96 - popd -fi - -if test "$setup_sc" = "1"; then - checkout sc $version_sc https://github.com/cksystemsgroup/scalloc - if test -f Makefile; then - echo "$devdir/scalloc is already configured; no need to reconfigure" - else - if test -f build/gyp/gyp; then - echo "$devdir/scalloc has the gyp tools installed; no need to re-download" - else - tools/make_deps.sh - fi - build/gyp/gyp --depth=. scalloc.gyp - fi - BUILDTYPE=Release make -j $procs - popd -fi - -if test "$setup_mi" = "1"; then - checkout mi $version_mi https://github.com/microsoft/mimalloc - - echo "" - echo "- build mimalloc release" - - cmake -B out/release - cmake --build out/release --parallel $procs - - echo "" - echo "- build mimalloc debug with full checking" - - cmake -B out/debug -DMI_CHECK_FULL=ON - cmake --build out/debug --parallel $procs - - echo "" - echo "- build mimalloc secure" - - cmake -B out/secure -DMI_SECURE=ON - cmake --build out/secure --parallel $procs - popd -fi - -if test "$setup_mi2" = "1"; then - checkout mi2 $version_mi2 https://github.com/microsoft/mimalloc - - echo "" - echo "- build mimalloc2 release" - - cmake -B out/release - cmake --build out/release --parallel $procs - - echo "" - echo "- build mimalloc2 debug with full checking" - - cmake -B out/debug -DMI_CHECK_FULL=ON - cmake --build out/debug --parallel $procs - - echo "" - echo "- build mimalloc2 secure" - - cmake -B out/secure -DMI_SECURE=ON - cmake --build out/secure --parallel $procs - popd -fi - -if test "$setup_mi3" = "1"; then - checkout mi3 $version_mi3 https://github.com/microsoft/mimalloc - - echo "" - echo "- build mimalloc3 release" - - cmake -B out/release - cmake --build out/release --parallel $procs - - echo "" - echo "- build mimalloc3 debug with full checking" - - cmake -B out/debug -DMI_CHECK_FULL=ON - cmake --build out/debug --parallel $procs - - echo "" - echo "- build mimalloc3 secure" - - cmake -B out/secure -DMI_SECURE=ON - cmake --build out/secure --parallel $procs - popd -fi - -if test "$setup_yal" = "1"; then - checkout yal $version_yal https://github.com/jorisgeer/yalloc - ./build.sh -V -fi - -phase "install benchmarks" - -if test "$setup_rocksdb" = "1"; then - phase "build rocksdb $version_rocksdb" - - pushd "$devdir" - if test -d "rocksdb-$version_rocksdb"; then - echo "$devdir/rocksdb-$version_rocksdb already exists; no need to download it" - else - wget --no-verbose "https://github.com/facebook/rocksdb/archive/refs/tags/v$version_rocksdb.tar.gz" -O rocksdb-$version_rocksdb.tar.gz - tar xzf "rocksdb-$version_rocksdb.tar.gz" - rm "./rocksdb-$version_rocksdb.tar.gz" - fi - - cd "rocksdb-$version_rocksdb" - # musl defines neither _POSIX_C_SOURCE nor _XOPEN_SOURCE by default, so - # without this rocksdb allocates its cache shards with plain malloc - set +e - patch -p1 -N -r- < ../../patches/rocksdb_cacheline_alloc.patch - set -e - DISABLE_WARNING_AS_ERROR=1 DISABLE_JEMALLOC=1 ROCKSDB_DISABLE_TCMALLOC=1 make db_bench -j $procs - [ "$CI" ] && find . -name '*.o' -delete - popd -fi - -if test "$setup_lean" = "1"; then - phase "build lean $version_lean" - checkout lean $version_lean https://github.com/leanprover-community/lean - set +e - patch -p1 -N -r- < ../../patches/lean.patch - set -e - mkdir -p out/release - cd out/release - env CC=gcc CXX="g++" cmake ../../src -DCUSTOM_ALLOCATORS=OFF -DLEAN_EXTRA_CXX_FLAGS="-w" -DCMAKE_POLICY_VERSION_MINIMUM=3.5 - echo "make -j$procs" - make -j $procs - rm -rf ./tests/ # we don't need tests - popd - checkout mathlib $version_mathlib https://github.com/leanprover-community/mathlib3 - popd -fi - -if test "$setup_redis" = "1"; then - phase "build redis $version_redis" - - pushd "$devdir" - if test -d "redis-$version_redis"; then - echo "$devdir/redis-$version_redis already exists; no need to download it" - else - wget --no-verbose "https://download.redis.io/releases/redis-$version_redis.tar.gz" - tar xzf "redis-$version_redis.tar.gz" - rm "./redis-$version_redis.tar.gz" - fi - - cd "redis-$version_redis/src" - USE_JEMALLOC=no MALLOC=libc BUILD_TLS=no make -j $procs - popd -fi - -if test "$setup_bench" = "1"; then - phase "patch shbench" - pushd "bench/shbench" - if test -f sh6bench-new.c; then - echo "do nothing: bench/shbench/sh6bench-new.c already exists" - else - wget --no-verbose http://www.microquill.com/smartheap/shbench/bench.zip - check_checksum "bench.zip" "$sha256sum_sh6bench" - unzip -o bench.zip - dos2unix sh6bench.patch - dos2unix sh6bench.c - patch -p1 -o sh6bench-new.c sh6bench.c sh6bench.patch - fi - if test -f sh8bench-new.c; then - echo "do nothing: bench/shbench/sh8bench-new.c already exists" - else - wget --no-verbose http://www.microquill.com/smartheap/SH8BENCH.zip - check_checksum "SH8BENCH.zip" "$sha256sum_sh8bench" - unzip -o SH8BENCH.zip - dos2unix sh8bench.patch - dos2unix SH8BENCH.C - patch -p1 -o sh8bench-new.c SH8BENCH.C sh8bench.patch - fi - popd - - phase "get large PDF document" - - readonly pdfdoc="large.pdf" - readonly pdfurl="https://raw.githubusercontent.com/geekaaron/Resources/master/resources/Writing_a_Simple_Operating_System--from_Scratch.pdf " - #readonly pdfurl="https://www.intel.com/content/dam/develop/external/us/en/documents/325462-sdm-vol-1-2abcd-3abcd-508360.pdf" - pushd "$devdir" - if test -f "$pdfdoc"; then - echo "do nothing: $devdir/$pdfdoc already exists" - else - useragent="Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:95.0) Gecko/20100101 Firefox/95.0" - wget --no-verbose -O "$pdfdoc" -U "useragent" $pdfurl - fi - popd - - phase "get lua" - checkout lua $version_lua https://github.com/lua/lua - popd - - phase "build benchmarks" - - cmake -B out/bench -S bench - cmake --build out/bench --parallel $procs -fi - -if test "$setup_linux" = "1"; then - phase "fetch linux" - pushd "$devdir" - if test -d "linux-$version_linux"; then - echo "$devdir/linux-$version_linux already exists; no need to download it" - else - wget --no-verbose "https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-$version_linux.tar.xz" - tar xf "linux-$version_linux.tar.xz" - rm "./linux-$version_linux.tar.xz" - fi - popd -fi - -curdir=`pwd` - -phase "installed allocators" -cat $devdir/version_*.txt 2>/dev/null | tee $devdir/versions.txt | column -t || true - -phase "done in $curdir" -echo "run the cfrac benchmarks as:" -echo "> cd out/bench" -echo "> ../../bench.sh alla cfrac" -echo -echo "to see all options use:" -echo "> ../../bench.sh help" -echo diff --git a/patches/hoard.patch b/patches/hoard.patch new file mode 100644 index 0000000..741edc7 --- /dev/null +++ b/patches/hoard.patch @@ -0,0 +1,17 @@ +diff --git a/src/source/libhoard.cpp b/src/source/libhoard.cpp +index 0f7567a..0b36a79 100644 +--- a/src/source/libhoard.cpp ++++ b/src/source/libhoard.cpp +@@ -163,3 +163,12 @@ extern "C" { + // include gnuwrapper here to aid inlining of xxmalloc + friends + #include "wrappers/gnuwrapper.cpp" + #endif ++ ++ ++// Heap-Layers' macwrapper.cpp defines these as weak defaults; its linux ++// wrapper.cpp calls them but libhoard.cpp did not define them, so libhoard.so ++// ended up with undefined symbols. ++extern "C" { ++ __attribute__((weak)) void xxfree_sized (void * ptr, size_t) { xxfree(ptr); } ++ __attribute__((weak)) void xxfree_aligned_sized (void * ptr, size_t, size_t) { xxfree(ptr); } ++} diff --git a/patches/tcg.patch b/patches/tcg.patch new file mode 100644 index 0000000..efc379e --- /dev/null +++ b/patches/tcg.patch @@ -0,0 +1,14 @@ +diff --git a/tcmalloc/BUILD b/tcmalloc/BUILD +index 47b0f065..cfb1570a 100644 +--- a/tcmalloc/BUILD ++++ b/tcmalloc/BUILD +@@ -1610,3 +1610,9 @@ cc_library( + ], + deps = ["@com_google_absl//absl/base:core_headers"], + ) ++ ++cc_binary( ++ name = "libtcmalloc.so", ++ linkshared = 1, ++ deps = [":tcmalloc"], ++)