Skip to content

Commit f82277b

Browse files
perf: Improve CPU performance on x64 and arm64 (#1968)
1 parent 4c9bbee commit f82277b

10 files changed

Lines changed: 320 additions & 219 deletions

File tree

.github/scripts/build-cpu.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,11 @@ declare build_os
44

55
set -xeuo pipefail
66

7-
pip install cmake==3.28.3
7+
if [[ "${build_os}" == windows* ]]; then
8+
pip install cmake==3.30.9
9+
else
10+
pip install cmake==3.28.3
11+
fi
812

913
if [ "${build_os:0:5}" == macos ] && [ "${build_arch}" == aarch64 ]; then
1014
cmake -DCMAKE_OSX_ARCHITECTURES=arm64 -DCOMPUTE_BACKEND=cpu .

CMakeLists.txt

Lines changed: 42 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ if (BUILD_CPU)
118118
set(CMAKE_CXX_STANDARD 17)
119119
set(CMAKE_CXX_STANDARD_REQUIRED ON)
120120
string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" HOST_ARCH)
121+
if(MSVC)
122+
# Use the experimental OpenMP runtime for persistent thread pool support.
123+
# Requires CMake 3.30+; silently ignored on older CMake versions.
124+
set(OpenMP_RUNTIME_MSVC "experimental")
125+
endif()
121126
find_package(OpenMP)
122127
endif()
123128

@@ -350,35 +355,52 @@ set_source_files_properties(${CPP_FILES} PROPERTIES LANGUAGE CXX)
350355
add_library(bitsandbytes SHARED ${SRC_FILES})
351356
target_compile_features(bitsandbytes PUBLIC cxx_std_17)
352357
target_include_directories(bitsandbytes PUBLIC csrc)
358+
set_target_properties(bitsandbytes PROPERTIES VISIBILITY_INLINES_HIDDEN ON)
353359

354360
if (BUILD_CPU)
361+
include(CheckIPOSupported)
362+
check_ipo_supported(RESULT ipo_supported OUTPUT ipo_output)
363+
if (ipo_supported AND NOT MSVC)
364+
set_property(TARGET bitsandbytes PROPERTY INTERPROCEDURAL_OPTIMIZATION TRUE)
365+
endif()
366+
355367
if (OpenMP_CXX_FOUND)
356368
target_link_libraries(bitsandbytes PRIVATE OpenMP::OpenMP_CXX)
357369
add_definitions(-DHAS_OPENMP)
358370
endif()
359371

360-
if ((HOST_ARCH MATCHES "x86_64|amd64") AND (NOT MSVC))
361-
include(CheckCXXCompilerFlag)
362-
check_cxx_compiler_flag(-mavx512f HAS_AVX512F_FLAG)
363-
check_cxx_compiler_flag(-mavx512bf16 HAS_AVX512BF16_FLAG)
364-
if (HAS_AVX512F_FLAG)
365-
target_compile_options(bitsandbytes PRIVATE -mavx512f)
366-
target_compile_options(bitsandbytes PRIVATE -mavx512dq)
367-
target_compile_options(bitsandbytes PRIVATE -mavx512bw)
368-
target_compile_options(bitsandbytes PRIVATE -mavx512vl)
372+
if (NOT MSVC)
373+
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
374+
target_compile_options(bitsandbytes PRIVATE -fno-semantic-interposition)
369375
endif()
370-
if (HAS_AVX512BF16_FLAG)
371-
target_compile_options(bitsandbytes PRIVATE -mavx512bf16)
376+
377+
if (HOST_ARCH MATCHES "x86_64|amd64")
378+
include(CheckCXXCompilerFlag)
379+
check_cxx_compiler_flag(-mavx512f HAS_AVX512F_FLAG)
380+
check_cxx_compiler_flag(-mavx512bf16 HAS_AVX512BF16_FLAG)
381+
if (HAS_AVX512F_FLAG)
382+
target_compile_options(
383+
bitsandbytes PRIVATE
384+
-mavx512f
385+
-mavx512bw
386+
-mavx512dq
387+
-mavx512vl
388+
)
389+
endif()
390+
if (HAS_AVX512BF16_FLAG)
391+
target_compile_options(bitsandbytes PRIVATE -mavx512bf16)
392+
endif()
393+
target_compile_options(
394+
bitsandbytes PRIVATE
395+
-mprefer-vector-width=256
396+
-mfma
397+
-mavx2
398+
-mf16c
399+
-mlzcnt
400+
-mbmi
401+
-mbmi2
402+
)
372403
endif()
373-
target_compile_options(
374-
bitsandbytes PRIVATE
375-
-mprefer-vector-width=256
376-
-mfma
377-
-mavx2
378-
-mlzcnt
379-
-mbmi
380-
-mbmi2
381-
)
382404
endif()
383405
endif()
384406

bitsandbytes/backends/cpu/ops.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@
2020
# However, we can overflow if we use this without AVX512_VNNI support.
2121
# This is fixed in torch 2.6+, so we set this as the minimum to be safe.
2222
# For more information: https://github.com/pytorch/pytorch/pull/136942
23-
# TODO(matthewdouglas): aarch64?
24-
if torch.__version__ >= (2, 6):
23+
#
24+
# Without AVX-512 (including aarch64), torch._int_mm uses a scalar fallback
25+
# that is much slower than fp32 matmul. Only use it when AVX-512 is available.
26+
if torch.__version__ >= (2, 6) and _has_avx512:
2527

2628
@register_kernel("bitsandbytes::int8_linear_matmul", "cpu")
2729
def _(A: torch.Tensor, B: torch.Tensor):

0 commit comments

Comments
 (0)