Skip to content

Commit 422150b

Browse files
dneto0Zackery Mason-Blaug
andauthored
Add mimalloc to improve multithreaded performance (KhronosGroup#6188)
Co-authored-by: Zackery Mason-Blaug <[email protected]>
1 parent da0ec29 commit 422150b

File tree

12 files changed

+154
-4
lines changed

12 files changed

+154
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ compile_commands.json
1111
/external/effcee
1212
/external/re2
1313
/external/protobuf
14+
/external/mimalloc
1415
/out
1516
/TAGS
1617
/third_party/llvm-build/

BUILD.bazel

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ cc_library(
131131
"source/*.cpp",
132132
"source/util/*.cpp",
133133
"source/val/*.cpp",
134+
], exclude = [
135+
"source/mimalloc.cpp"
134136
]) + [
135137
":build_version_inc",
136138
":gen_compressed_tables",

DEPS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ vars = {
1515
're2_revision': 'c84a140c93352cdabbfb547c531be34515b12228',
1616

1717
'spirv_headers_revision': '2a611a970fdbc41ac2e3e328802aed9985352dca',
18+
19+
'mimalloc_revision': '51c09e7b6a0ac5feeba998710f00c7dd7aa67bbf',
1820
}
1921

2022
deps = {
@@ -36,5 +38,8 @@ deps = {
3638
'external/spirv-headers':
3739
Var('github') + '/KhronosGroup/SPIRV-Headers.git@' +
3840
Var('spirv_headers_revision'),
41+
42+
'external/mimalloc':
43+
Var('github') + '/microsoft/mimalloc.git@' + Var('mimalloc_revision'),
3944
}
4045

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ For some kinds of development, you may need the latest sources from the third-pa
300300
git clone https://github.com/google/effcee.git spirv-tools/external/effcee
301301
git clone https://github.com/google/re2.git spirv-tools/external/re2
302302
git clone https://github.com/abseil/abseil-cpp.git spirv-tools/external/abseil_cpp
303+
git clone https://github.com/microsoft/mimalloc.git spirv-tools/external/mimalloc
303304

304305
#### Dependency on Effcee
305306

@@ -312,6 +313,23 @@ Effcee itself depends on [RE2][re2], and RE2 depends on [Abseil][abseil-cpp].
312313
RE2 sources to appear in `external/re2`, and Abseil sources to appear in
313314
`external/abseil_cpp`.
314315

316+
#### Dependency on mimalloc
317+
318+
SPIRV-Tools may be configured to use the [mimalloc][mimalloc] library to improve memory
319+
allocation performance. In order to avoid unexpectedly changing allocation behavior of
320+
applications that link SPIRV-Tools libraries statically, this option has no effect on
321+
the static libraries.
322+
323+
In the CMake build, usage of mimalloc is controlled by the `SPIRV_TOOLS_USE_MIMALLOC`
324+
option. This variable defaults on `ON` when building for Windows and `OFF` when building
325+
for other platforms. Enabling this option on non-Windows platforms is supported and is
326+
expected to work normally, but this has not been tested as thoroughly and extensively as
327+
the Windows version. In the future, the `SPIRV_TOOLS_USE_MIMALLOC` option may default to
328+
`ON` for non-Windows platforms as well.
329+
330+
*Note*: mimalloc is currently only supported when building with CMake. When using Bazel,
331+
mimalloc is not used.
332+
315333
### Source code organization
316334

317335
* `example`: demo code of using SPIRV-Tools APIs
@@ -325,6 +343,7 @@ Effcee itself depends on [RE2][re2], and RE2 depends on [Abseil][abseil-cpp].
325343
* `external/abseil_cpp`: Location of [Abseil][abseil-cpp] sources, if Abseil is
326344
not already configured by an enclosing project.
327345
(The RE2 project already requires Abseil.)
346+
* `external/mimalloc`: Intended location for [mimalloc][mimalloc] sources, not provided
328347
* `include/`: API clients should add this directory to the include search path
329348
* `external/spirv-headers`: Intended location for
330349
[SPIR-V headers][spirv-headers], not provided
@@ -801,6 +820,7 @@ limitations under the License.
801820
[effcee]: https://github.com/google/effcee
802821
[re2]: https://github.com/google/re2
803822
[abseil-cpp]: https://github.com/abseil/abseil-cpp
823+
[mimalloc]: https://github.com/microsoft/mimalloc
804824
[CMake]: https://cmake.org/
805825
[cpp-style-guide]: https://google.github.io/styleguide/cppguide.html
806826
[clang-sanitizers]: http://clang.llvm.org/docs/UsersManual.html#controlling-code-generation

external/CMakeLists.txt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,46 @@ function(pop_variable var)
2626
set(${var} ${val} PARENT_SCOPE)
2727
endfunction()
2828

29+
if (DEFINED mimalloc_SOURCE_DIR)
30+
# This allows flexible position of the mimalloc repo.
31+
set(MIMALLOC_DIR ${mimalloc_SOURCE_DIR})
32+
else()
33+
if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/mimalloc)
34+
set(MIMALLOC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/mimalloc)
35+
endif()
36+
endif()
37+
38+
# Used on Windows by default, but allow opt-in on other platforms
39+
if (WIN32)
40+
set(SPIRV_TOOLS_USE_MIMALLOC_DEFAULT_VALUE ON)
41+
else()
42+
set(SPIRV_TOOLS_USE_MIMALLOC_DEFAULT_VALUE OFF)
43+
endif()
44+
45+
# To avoid unexpected side effects on users of the static library, mimalloc
46+
# may only be used when building executables and shared libraries.
47+
include(CMakeDependentOption)
48+
cmake_dependent_option(SPIRV_TOOLS_USE_MIMALLOC
49+
"Executables and shared libraries use mimalloc instead of the default allocator"
50+
${SPIRV_TOOLS_USE_MIMALLOC_DEFAULT_VALUE} "MIMALLOC_DIR" OFF)
51+
52+
if (SPIRV_TOOLS_USE_MIMALLOC)
53+
if (NOT WIN32)
54+
push_variable(MI_OVERRIDE 0)
55+
endif()
56+
push_variable(MI_BUILD_TESTS 0)
57+
58+
add_subdirectory(${MIMALLOC_DIR} ${CMAKE_BINARY_DIR}/external/mimalloc EXCLUDE_FROM_ALL)
59+
if (${CMAKE_CXX_COMPILER_ID} MATCHES Clang)
60+
target_compile_options(mimalloc-static PRIVATE -Wno-int-conversion)
61+
endif()
62+
63+
if (NOT WIN32)
64+
pop_variable(MI_OVERRIDE)
65+
endif()
66+
pop_variable(MI_BUILD_TESTS)
67+
endif()
68+
2969
if (DEFINED SPIRV-Headers_SOURCE_DIR)
3070
# This allows flexible position of the SPIRV-Headers repo.
3171
set(SPIRV_HEADER_DIR ${SPIRV-Headers_SOURCE_DIR})

source/CMakeLists.txt

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,12 @@ if (${SPIRV_TIMER_ENABLED})
297297
${CMAKE_CURRENT_SOURCE_DIR}/util/timer.cpp)
298298
endif()
299299

300+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
301+
set(SPIRV_SOURCES
302+
${SPIRV_SOURCES}
303+
${CMAKE_CURRENT_SOURCE_DIR}/mimalloc.cpp)
304+
endif()
305+
300306
# The software_version.cpp file includes build-version.inc.
301307
# Rebuild the software_version.cpp object file if it is older than
302308
# build-version.inc or whenever build-version.inc itself is out of
@@ -333,6 +339,9 @@ endfunction()
333339
# Always build ${SPIRV_TOOLS}-shared. This is expected distro packages, and
334340
# unlike the other SPIRV_TOOLS target, defaults to hidden symbol visibility.
335341
add_library(${SPIRV_TOOLS}-shared SHARED ${SPIRV_SOURCES})
342+
if (SPIRV_TOOLS_USE_MIMALLOC)
343+
target_link_libraries(${SPIRV_TOOLS}-shared PRIVATE mimalloc-static)
344+
endif()
336345
spirv_tools_default_target_options(${SPIRV_TOOLS}-shared)
337346
set_target_properties(${SPIRV_TOOLS}-shared PROPERTIES CXX_VISIBILITY_PRESET hidden)
338347
target_compile_definitions(${SPIRV_TOOLS}-shared
@@ -357,6 +366,9 @@ if(SPIRV_TOOLS_BUILD_STATIC)
357366
set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS}-static ${SPIRV_TOOLS}-shared)
358367
else()
359368
add_library(${SPIRV_TOOLS} ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_SOURCES})
369+
if (SPIRV_TOOLS_USE_MIMALLOC)
370+
target_link_libraries(${SPIRV_TOOLS} PRIVATE mimalloc-static)
371+
endif()
360372
spirv_tools_default_target_options(${SPIRV_TOOLS})
361373
set(SPIRV_TOOLS_TARGETS ${SPIRV_TOOLS} ${SPIRV_TOOLS}-shared)
362374
endif()
@@ -365,12 +377,15 @@ if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux")
365377
find_library(LIBRT rt)
366378
if(LIBRT)
367379
foreach(target ${SPIRV_TOOLS_TARGETS})
368-
target_link_libraries(${target} rt)
380+
target_link_libraries(${target} PUBLIC rt)
369381
endforeach()
370382
endif()
371383
endif()
372384

373385
if(ENABLE_SPIRV_TOOLS_INSTALL)
386+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
387+
list(APPEND SPIRV_TOOLS_TARGETS mimalloc-static)
388+
endif()
374389
install(TARGETS ${SPIRV_TOOLS_TARGETS} EXPORT ${SPIRV_TOOLS}Targets)
375390
export(EXPORT ${SPIRV_TOOLS}Targets FILE ${SPIRV_TOOLS}Target.cmake)
376391

source/diff/CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,16 @@ set(SPIRV_TOOLS_DIFF_SOURCES
1818
diff.cpp
1919
)
2020

21+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
22+
list(APPEND SPIRV_TOOLS_DIFF_SOURCES ${spirv-tools_SOURCE_DIR}/source/mimalloc.cpp)
23+
endif()
24+
2125
add_library(SPIRV-Tools-diff ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_DIFF_SOURCES})
2226

27+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
28+
target_link_libraries(SPIRV-Tools-diff PRIVATE mimalloc-static)
29+
endif()
30+
2331
spvtools_default_compile_options(SPIRV-Tools-diff)
2432
target_include_directories(SPIRV-Tools-diff
2533
PUBLIC
@@ -39,7 +47,13 @@ set_property(TARGET SPIRV-Tools-diff PROPERTY FOLDER "SPIRV-Tools libraries")
3947
spvtools_check_symbol_exports(SPIRV-Tools-diff)
4048

4149
if(ENABLE_SPIRV_TOOLS_INSTALL)
42-
install(TARGETS SPIRV-Tools-diff EXPORT SPIRV-Tools-diffTargets)
50+
set(SPIRV-Tools-diff-InstallTargets SPIRV-Tools-diff)
51+
52+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
53+
list(APPEND SPIRV-Tools-diff-InstallTargets mimalloc-static)
54+
endif()
55+
56+
install(TARGETS ${SPIRV-Tools-diff-InstallTargets} EXPORT SPIRV-Tools-diffTargets)
4357
export(EXPORT SPIRV-Tools-diffTargets FILE SPIRV-Tools-diffTargets.cmake)
4458

4559
spvtools_config_package_dir(SPIRV-Tools-diff PACKAGE_DIR)

source/fuzz/CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,8 +438,16 @@ if(SPIRV_BUILD_FUZZER)
438438

439439
spvtools_pch(SPIRV_TOOLS_FUZZ_SOURCES pch_source_fuzz)
440440

441+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
442+
list(APPEND SPIRV_TOOLS_DIFF_SOURCES ${spirv-tools_SOURCE_DIR}/source/mimalloc.cpp)
443+
endif()
444+
441445
add_library(SPIRV-Tools-fuzz ${SPIRV_TOOLS_FUZZ_SOURCES})
442446

447+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
448+
target_link_libraries(SPIRV-Tools-fuzz PRIVATE mimalloc-static)
449+
endif()
450+
443451
spvtools_default_compile_options(SPIRV-Tools-fuzz)
444452

445453
# Compilation of the auto-generated protobuf source file will yield warnings,
@@ -470,7 +478,13 @@ if(SPIRV_BUILD_FUZZER)
470478
spvtools_check_symbol_exports(SPIRV-Tools-fuzz)
471479

472480
if(ENABLE_SPIRV_TOOLS_INSTALL)
473-
install(TARGETS SPIRV-Tools-fuzz EXPORT SPIRV-Tools-fuzzTargets)
481+
set(SPIRV-Tools-fuzz-InstallTargets SPIRV-Tools-fuzz)
482+
483+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
484+
list(APPEND SPIRV-Tools-fuzz-InstallTargets mimalloc-static)
485+
endif()
486+
487+
install(TARGETS ${SPIRV-Tools-fuzz-InstallTargets} EXPORT SPIRV-Tools-fuzzTargets)
474488
export(EXPORT SPIRV-Tools-fuzzTargets FILE SPIRV-Tools-fuzzTarget.cmake)
475489

476490
spvtools_config_package_dir(SPIRV-Tools-fuzz PACKAGE_DIR)

source/mimalloc.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Copyright (c) 2025 The Khronos Group Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "mimalloc-new-delete.h"

source/opt/CMakeLists.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,16 @@ endif()
260260

261261
spvtools_pch(SPIRV_TOOLS_OPT_SOURCES pch_source_opt)
262262

263+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
264+
list(APPEND SPIRV_TOOLS_OPT_SOURCES ${spirv-tools_SOURCE_DIR}/source/mimalloc.cpp)
265+
endif()
266+
263267
add_library(SPIRV-Tools-opt ${SPIRV_TOOLS_LIBRARY_TYPE} ${SPIRV_TOOLS_OPT_SOURCES})
264268

269+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
270+
target_link_libraries(SPIRV-Tools-opt PRIVATE mimalloc-static)
271+
endif()
272+
265273
spvtools_default_compile_options(SPIRV-Tools-opt)
266274
target_include_directories(SPIRV-Tools-opt
267275
PUBLIC
@@ -278,7 +286,13 @@ set_property(TARGET SPIRV-Tools-opt PROPERTY FOLDER "SPIRV-Tools libraries")
278286
spvtools_check_symbol_exports(SPIRV-Tools-opt)
279287

280288
if(ENABLE_SPIRV_TOOLS_INSTALL)
281-
install(TARGETS SPIRV-Tools-opt EXPORT SPIRV-Tools-optTargets)
289+
set(SPIRV-Tools-opt-InstallTargets SPIRV-Tools-opt)
290+
291+
if (SPIRV_TOOLS_USE_MIMALLOC AND NOT SPIRV_TOOLS_BUILD_STATIC)
292+
list(APPEND SPIRV-Tools-opt-InstallTargets mimalloc-static)
293+
endif()
294+
295+
install(TARGETS ${SPIRV-Tools-opt-InstallTargets} EXPORT SPIRV-Tools-optTargets)
282296
export(EXPORT SPIRV-Tools-optTargets FILE SPIRV-Tools-optTargets.cmake)
283297

284298
spvtools_config_package_dir(SPIRV-Tools-opt PACKAGE_DIR)

0 commit comments

Comments
 (0)