Last active
April 18, 2025 04:57
-
-
Save MihaelIsaev/fbb0135e9b1bb1d2691bb71a30528bc6 to your computer and use it in GitHub Desktop.
Revisions
-
MihaelIsaev revised this gist
Apr 2, 2025 . 1 changed file with 13 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -3,6 +3,19 @@ According to the [Performance penalty from the Static Linux SDK](https://forums. ## Why? **It is important for swift apps – especially for server-side apps – to be performant** ## Doesn't Static Linux SDK already have mimalloc? Great question! Maybe in the future — who knows? If you're from the future, you can check your SDK by running ```bash llvm-nm libc.a | grep 'mi_' ``` If it returns nothing, then `mimalloc` hasn't been integrated yet — and you can integrate it by following this instruction If it returns a lot of `mi_`, then congrats — you've already got `mimalloc` in your SDK 🎉 ## Disclaimer You are doing it at your own risk 😱 -
MihaelIsaev revised this gist
Apr 2, 2025 . 1 changed file with 5 additions and 0 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -115,6 +115,11 @@ cd ../ 1. Download `mimalloc_v2.1.7.diff` and `patch_musl.sh` ```bash curl -LO https://gist.github.com/MihaelIsaev/fbb0135e9b1bb1d2691bb71a30528bc6/raw/4448da386e6d0dbd704716091be4818e56ba3d28/mimalloc_v2.1.7.diff curl -LO https://gist.github.com/MihaelIsaev/fbb0135e9b1bb1d2691bb71a30528bc6/raw/4448da386e6d0dbd704716091be4818e56ba3d28/patch_musl.sh ``` 2. Make `patch_musl.sh` executable ```bash -
MihaelIsaev created this gist
Apr 2, 2025 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,155 @@ According to the [Performance penalty from the Static Linux SDK](https://forums.swift.org/t/performance-penalty-from-the-static-linux-sdk/75003) post I would like to provide a step-by-step instruction of how to patch `static-linux-sdk` with `mimalloc` ## Why? **It is important for swift apps – especially for server-side apps – to be performant** ## Disclaimer You are doing it at your own risk 😱 ## Requirements **`x86_64` and `arm64` ubuntu/debian environment** Or docker with QEMU, but I had no luck with it yet. So I used `x86_64` and `arm64` machines on [Hetzner Cloud](http://cloud.hetzner.com) `static-linux-sdk` gives you the ability to compile into x86 and ARM architectures, it means that it has two versions of `libc.a`, one for each platform We have to patch both # Step-by-step ## Get SDK I assume you already have it installed on your machine, but if not then install or just download it ### Install ```bash swift sdk install <URL> --checksum <CHECKSUM> ``` ### Download SDK 1. Go to [swift.org](https://www.swift.org/install/linux/) 2. Choose Ubuntu or Debian 3. Choose version of OS 4.1. Hit the `Download Linux Static SDK` button 4.2 Or copy link and download it with `curl` e.g. `curl -LO <URL>` #### Extract SDK archive Let's assume you downloaded `swift-6.1-RELEASE_static-linux-0.0.1.artifactbundle.tar.gz` Then, execute ```bash tar -xzf swift-6.1-RELEASE_static-linux-0.0.1.artifactbundle.tar.gz ``` ## Take `libc.a` files from it Create `x86_64` and `aarch64` directories ```bash mkdir x86_64 && mkdir aarch64 ``` Copy both versions of `libc.a` into these directories If you have it installed then it is located at `~/.swiftpm/swift-sdks` If not then it is where you extracted it ```bash cp swift-6.1-RELEASE_static-linux-0.0.1.artifactbundle/swift-6.1-RELEASE_static-linux-0.0.1/swift-linux-musl/musl-1.2.5.sdk/x86_64/usr/lib/libc.a ./x86_64/libc.a cp swift-6.1-RELEASE_static-linux-0.0.1.artifactbundle/swift-6.1-RELEASE_static-linux-0.0.1/swift-linux-musl/musl-1.2.5.sdk/aarch64/usr/lib/libc.a ./aarch64/libc.a ``` ## Patching Do the following steps on both `x86_64` and `arm64` machines ### Install required packages via `apt` ```bash # install required packages apt update apt install -y llvm software-properties-common build-essential libssl-dev clang ``` ### Prepare cmake > [!Note] > `mimalloc` requires `cmake >= 3.18.0` Check your `cmake` version ```bash cmake --version ``` If it is lower, then install `3.27.9` from sources by following these steps ```bash # download cmake curl -LO https://github.com/Kitware/CMake/releases/download/v3.27.9/cmake-3.27.9.tar.gz # extract cmake tar -xf cmake-3.27.9.tar.gz # go to cmake dir cd cmake-3.27.9 # compile cmake ./bootstrap --prefix=$HOME/.local make -j$(nproc) make install # add cmake into PATH echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc source ~/.bashrc # check cmake version cmake --version # go back to the parent dir cd ../ ``` ### Download 1. Download `mimalloc_v2.1.7.diff` and `patch_musl.sh` 2. Make `patch_musl.sh` executable ```bash chmod +x ./patch_musl.sh ``` 3. Upload`libc.a` for the current CPU architecture ### Patch `libc.a` It will create `libc.a.bak` backup of the original file ```bash ./patch_musl.sh ``` 🥳 **Now you have successfully patched `libc.a` with `mimalloc`** > [!Tip] > Don't forget to patch it for both architectures ## Copy `libc.a` back into your SDK I assume you have it installed, so copy proper `libc.a` files into their `usr/lib` directories ## Do I need to put `libmimalloc.a` alongside `libc.a`? No, `mimalloc` has been merged into `libc.a` ## Docker version? I tried to do it but had no luck yet. You are welcome to implement it and update this instruction 🤝 ## Credits Credit to Sebastian Toivonen, aka [MarSe32m](https://forums.swift.org/u/MarSe32m) and his [post](https://forums.swift.org/t/performance-penalty-from-the-static-linux-sdk/75003) 🫡 **Enjoy!** This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,35 @@ diff --git a/CMakeLists.txt b/CMakeLists.txt index bcfe91d8..a5473c69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -481,7 +481,6 @@ endif() # static library if (MI_BUILD_STATIC) add_library(mimalloc-static STATIC ${mi_sources}) - set_property(TARGET mimalloc-static PROPERTY POSITION_INDEPENDENT_CODE ON) target_compile_definitions(mimalloc-static PRIVATE ${mi_defines} MI_STATIC_LIB) target_compile_options(mimalloc-static PRIVATE ${mi_cflags} ${mi_cflags_static}) target_link_libraries(mimalloc-static PRIVATE ${mi_libraries}) diff --git a/src/alloc-override.c b/src/alloc-override.c index 12837cdd..e5bcda22 100644 --- a/src/alloc-override.c +++ b/src/alloc-override.c @@ -191,7 +191,7 @@ typedef void* mi_nothrow_t; void* operator new[](std::size_t n, std::align_val_t al, const std::nothrow_t&) noexcept { return mi_new_aligned_nothrow(n, static_cast<size_t>(al)); } #endif -#elif (defined(__GNUC__) || defined(__clang__)) +#elif (defined(__GNUC__) || defined(__clang__) || defined(do_we_need_this)) // ------------------------------------------------------ // Override by defining the mangled C++ names of the operators (as // used by GCC and CLang). @@ -289,7 +289,7 @@ mi_decl_weak int reallocarr(void* p, size_t count, size_t size) { return mi_r void __libc_free(void* p) MI_FORWARD0(mi_free, p) void* __libc_memalign(size_t alignment, size_t size) { return mi_memalign(alignment, size); } -#elif defined(__GLIBC__) && defined(__linux__) +#elif defined(__linux__) //defined(__GLIBC__) && defined(__linux__) // forward __libc interface (needed for glibc-based Linux distributions) void* __libc_malloc(size_t size) MI_FORWARD1(mi_malloc,size) void* __libc_calloc(size_t count, size_t size) MI_FORWARD2(mi_calloc,count,size) This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,68 @@ #!/bin/bash set -euo pipefail echo "Looking for libc.a in current directory..." LIBC_PATH="./libc.a" if [ ! -f "$LIBC_PATH" ]; then echo "Error: libc.a not found in the current directory." exit 1 fi echo "Backing up original libc.a to libc.a.bak" cp "$LIBC_PATH" libc.a.bak echo "Building mimalloc static library..." if [ ! -d mimalloc ]; then echo "Cloning mimalloc..." git clone https://github.com/microsoft/mimalloc else echo "Using existing mimalloc directory." fi cd mimalloc git fetch --tags git checkout tags/v2.1.7 # Clean up any previous modifications git reset --hard git clean -fd # Check if patch is already applied if git apply --check ../mimalloc_v2.1.7.diff 2>/dev/null; then echo "Applying patch..." git apply ../mimalloc_v2.1.7.diff else echo "Patch already applied or incompatible. Skipping patch step." fi cmake -Bout -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=clang -DMI_BUILD_SHARED=OFF -DMI_BUILD_OBJECT=OFF -DMI_BUILD_TESTS=OFF . cmake --build out echo "Patching musl libc.a with mimalloc..." cp ./out/libmimalloc.a . cp "$OLDPWD/libc.a" . # Remove musl malloc-related object files for symbol in aligned_alloc calloc donate free free libc_calloc lite_malloc malloc malloc_usable_size memalign posix_memalign realloc realloc reallocarray valloc strdup strndup; do llvm-ar -d libc.a "${symbol}.lo" || true done # Verify removals for symbol in aligned_alloc calloc donate free libc_calloc lite_malloc malloc malloc_usable_size memalign posix_memalign realloc reallocarray valloc strdup strndup; do if llvm-ar -t libc.a | grep -q "${symbol}.lo"; then echo "Warning: ${symbol}.lo still exists in libc.a" fi done # Inject mimalloc object files llvm-ar -x libmimalloc.a llvm-ar -r libc.a *.o echo "Replacing original libc.a with patched version..." cp libc.a "$OLDPWD/libc.a" cd "$OLDPWD" rm -rf mimalloc echo "✅ Done! libc.a has been patched with mimalloc."