CPU 构建选项#

描述#

以下选项主要用于更改针对特定 CPU 功能的优化的默认行为

  • cpu-baseline: 最小的 CPU 功能集。

    默认值为 min,它提供了可以在处理器系列中广泛的平台上安全运行的最小 CPU 功能。

    注意

    在运行时,如果 NumPy 模块无法在目标 CPU 上找到任何指定的 CPU 功能,则加载模块将失败(引发 Python 运行时错误)。

  • cpu-dispatch: 派遣的 CPU 功能集。

    默认值为 max -xop -fma4,它启用了所有 CPU 功能,除了 AMD 的遗留功能(在 X86 的情况下)。

    注意

    在运行时,NumPy 模块将跳过目标 CPU 中不可用的任何指定功能。

这些选项在构建时可以通过向 meson-python 传递设置参数来访问,这些参数通过构建前端(例如 pipbuild)传递。它们接受一组CPU 功能或收集多个功能的功能组,或者特殊选项,这些选项执行一系列过程。

要自定义 CPU/构建选项

pip install . -Csetup-args=-Dcpu-baseline="avx2 fma3" -Csetup-args=-Dcpu-dispatch="max"

快速入门#

通常,默认设置倾向于不强制执行某些 CPU 功能,这些功能可能在某些旧处理器上不可用。提高基线功能的上限通常会提高性能,也可能减小二进制文件的大小。

以下是可能需要更改默认设置的最常见场景

我正在为本地使用构建 NumPy#

并且我不打算将构建导出给其他用户或将目标 CPU 设置为与主机不同的 CPU。

对于基线,设置 native,或者在 native 选项不受您的平台支持的情况下,手动指定 CPU 功能

python -m build --wheel -Csetup-args=-Dcpu-baseline="native"

在这种情况下,无需使用额外的 CPU 功能构建 NumPy,因为所有支持的功能都已在基线功能中定义

python -m build --wheel -Csetup-args=-Dcpu-baseline="native" \
-Csetup-args=-Dcpu-dispatch="none"

注意

如果 native 不受主机平台支持,则会引发致命错误。

我不希望支持 x86 架构的旧处理器#

由于大多数 CPU 现在都至少支持 AVXF16C 功能,您可以使用

python -m build --wheel -Csetup-args=-Dcpu-baseline="avx f16c"

注意

cpu-baseline 强制组合所有隐含的功能,因此无需添加 SSE 功能。

我遇到了上述相同的情况,但使用的是 ppc64 架构#

然后将基线功能的上限提高到 Power8

python -m build --wheel -Csetup-args=-Dcpu-baseline="vsx2"

在使用 AVX512 功能时遇到问题?#

您可能对包含 AVX512 或任何其他 CPU 功能持保留意见,并且希望从派发的功能中排除它

python -m build --wheel -Csetup-args=-Dcpu-dispatch="max -avx512f -avx512cd \
-avx512_knl -avx512_knm -avx512_skx -avx512_clx -avx512_cnl -avx512_icl"

支持的功能#

功能名称可以表示一项功能或一组功能,如以下表格所示,支持的功能取决于最低的兴趣

注意

以下功能可能并非所有编译器都支持,此外,在遇到 AVX512AVX2FMA3 等功能时,某些编译器可能会产生不同的隐含功能集。有关更多详细信息,请参见平台差异

在 x86 上#

名称

隐含

收集

SSE

SSE2

SSE2

SSE

SSE3

SSE SSE2

SSSE3

SSE SSE2 SSE3

SSE41

SSE SSE2 SSE3 SSSE3

POPCNT

SSE SSE2 SSE3 SSSE3 SSE41

SSE42

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT

AVX

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42

XOP

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX

FMA4

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX

F16C

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX

FMA3

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C

AVX2

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C

AVX512F

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2

AVX512CD

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F

AVX512_KNL

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD

AVX512ER AVX512PF

AVX512_KNM

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_KNL

AVX5124FMAPS AVX5124VNNIW AVX512VPOPCNTDQ

AVX512_SKX

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD

AVX512VL AVX512BW AVX512DQ

AVX512_CLX

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_SKX

AVX512VNNI

AVX512_CNL

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_SKX

AVX512IFMA AVX512VBMI

AVX512_ICL

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_SKX AVX512_CLX AVX512_CNL

AVX512VBMI2 AVX512BITALG AVX512VPOPCNTDQ

AVX512_SPR

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_SKX AVX512_CLX AVX512_CNL AVX512_ICL

AVX512FP16

在 IBM/POWER 大端上#

名称

隐含

VSX

VSX2

VSX

VSX3

VSX VSX2

VSX4

VSX VSX2 VSX3

在 IBM/POWER 小端上#

名称

隐含

VSX

VSX2

VSX2

VSX

VSX3

VSX VSX2

VSX4

VSX VSX2 VSX3

在 ARMv7/A32 上#

名称

隐含

NEON

NEON_FP16

NEON

NEON_VFPV4

NEON NEON_FP16

ASIMD

NEON NEON_FP16 NEON_VFPV4

ASIMDHP

NEON NEON_FP16 NEON_VFPV4 ASIMD

ASIMDDP

NEON NEON_FP16 NEON_VFPV4 ASIMD

ASIMDFHM

NEON NEON_FP16 NEON_VFPV4 ASIMD ASIMDHP

在 ARMv8/A64 上#

名称

隐含

NEON

NEON_FP16 NEON_VFPV4 ASIMD

NEON_FP16

NEON NEON_VFPV4 ASIMD

NEON_VFPV4

NEON NEON_FP16 ASIMD

ASIMD

NEON NEON_FP16 NEON_VFPV4

ASIMDHP

NEON NEON_FP16 NEON_VFPV4 ASIMD

ASIMDDP

NEON NEON_FP16 NEON_VFPV4 ASIMD

ASIMDFHM

NEON NEON_FP16 NEON_VFPV4 ASIMD ASIMDHP

在 IBM/ZSYSTEM(S390X)#

名称

隐含

VX

VXE

VX

VXE2

VX VXE

特殊选项#

  • NONE: 不启用任何功能。

  • NATIVE: 启用主机 CPU 支持的所有 CPU 功能,此操作基于编译器标志 (-march=native, -xHost, /QxHost)

  • MIN: 启用可以在各种平台上安全运行的最小 CPU 功能

    对于 Arch

    隐含

    x86(32 位模式)

    SSE SSE2

    x86_64

    SSE SSE2 SSE3

    IBM/POWER(大端模式)

    NONE

    IBM/POWER(小端模式)

    VSX VSX2

    ARMHF

    NONE

    ARM64 A.K. AARCH64

    NEON NEON_FP16 NEON_VFPV4 ASIMD

    IBM/ZSYSTEM(S390X)

    NONE

  • MAX: 启用编译器和平台支持的所有 CPU 功能。

  • Operators-/+: 删除或添加功能,在 MAXMINNATIVE 选项中很有用。

行为#

  • CPU 功能和其他选项不区分大小写,例如

    python -m build --wheel -Csetup-args=-Dcpu-dispatch="SSE41 avx2 FMA3"
    
  • 请求的优化顺序无关紧要

    python -m build --wheel -Csetup-args=-Dcpu-dispatch="SSE41 AVX2 FMA3"
    # equivalent to
    python -m build --wheel -Csetup-args=-Dcpu-dispatch="FMA3 AVX2 SSE41"
    
  • 可以使用逗号、空格或“+”作为分隔符,例如

    python -m build --wheel -Csetup-args=-Dcpu-dispatch="avx2 avx512f"
    # or
    python -m build --wheel -Csetup-args=-Dcpu-dispatch=avx2,avx512f
    # or
    python -m build --wheel -Csetup-args=-Dcpu-dispatch="avx2+avx512f"
    

    所有都有效,但如果使用空格,则应将参数用引号括起来或用反斜杠转义。

  • cpu-baseline 组合所有隐含的 CPU 功能,例如

    python -m build --wheel -Csetup-args=-Dcpu-baseline=sse42
    # equivalent to
    python -m build --wheel -Csetup-args=-Dcpu-baseline="sse sse2 sse3 ssse3 sse41 popcnt sse42"
    
  • 如果编译器原生标志 -march=native-xHost/QxHost 通过环境变量 CFLAGS 启用,则 cpu-baseline 将被视为“native”。

    export CFLAGS="-march=native"
    pip install .
    # is equivalent to
    pip install . -Csetup-args=-Dcpu-baseline=native
    
  • cpu-baseline 会转义目标平台或编译器不支持的任何指定功能,而不是引发致命错误。

    注意

    由于 cpu-baseline 组合了所有隐含的功能,因此将启用隐含功能的最大支持值,而不是转义所有这些功能。例如

    # Requesting `AVX2,FMA3` but the compiler only support **SSE** features
    python -m build --wheel -Csetup-args=-Dcpu-baseline="avx2 fma3"
    # is equivalent to
    python -m build --wheel -Csetup-args=-Dcpu-baseline="sse sse2 sse3 ssse3 sse41 popcnt sse42"
    
  • cpu-dispatch 不会组合任何隐含的 CPU 功能,因此您必须添加它们,除非您想禁用其中一个或全部。

    # Only dispatches AVX2 and FMA3
    python -m build --wheel -Csetup-args=-Dcpu-dispatch=avx2,fma3
    # Dispatches AVX and SSE features
    python -m build --wheel -Csetup-args=-Dcpu-dispatch=ssse3,sse41,sse42,avx,avx2,fma3
    
  • cpu-dispatch 会转义任何指定的基线功能,还会转义目标平台或编译器不支持的任何功能,而不会引发致命错误。

最终,您应该始终检查构建日志中的最终报告,以验证启用的功能。有关更多详细信息,请参阅 构建报告

平台差异#

某些特殊情况会迫使我们在某些编译器或架构方面将某些功能链接在一起,从而导致无法单独构建它们。

这些情况可以分为两部分,如下所示

架构兼容性

需要对齐某些 CPU 功能,这些功能保证由同一架构的后续几代支持,某些情况下

  • 在 ppc64le 上,VSX(ISA 2.06)VSX2(ISA 2.07) 互相暗示,因为第一个支持小端模式的版本是 Power-8`(ISA 2.07)`

  • 在 AArch64 上,NEON NEON_FP16 NEON_VFPV4 ASIMD 互相暗示,因为它们是硬件基线的一部分。

例如

# On ARMv8/A64, specify NEON is going to enable Advanced SIMD
# and all predecessor extensions
python -m build --wheel -Csetup-args=-Dcpu-baseline=neon
# which is equivalent to
python -m build --wheel -Csetup-args=-Dcpu-baseline="neon neon_fp16 neon_vfpv4 asimd"

注意

请仔细查看 支持的功能,以确定互相暗示的功能。

编译兼容性

某些编译器无法为所有 CPU 功能提供独立支持。例如,**Intel** 的编译器没有为 AVX2FMA3 提供单独的标志,这很有意义,因为所有带有 AVX2 的 Intel CPU 也支持 FMA3,但这种方法与来自 **AMD** 或 **VIA** 的其他 **x86** CPU 不兼容。

例如

# Specify AVX2 will force enables FMA3 on Intel compilers
python -m build --wheel -Csetup-args=-Dcpu-baseline=avx2
# which is equivalent to
python -m build --wheel -Csetup-args=-Dcpu-baseline="avx2 fma3"

下表仅显示了一些编译器在 支持的功能 表中显示的一般上下文中强加的差异

注意

带删除线的特征名称表示不支持的 CPU 特征。

在 x86::Intel 编译器上#

名称

隐含

收集

FMA3

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C AVX2

AVX2

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3

AVX512F

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512CD

XOP

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX

FMA4

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX

AVX512_SPR

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_SKX AVX512_CLX AVX512_CNL AVX512_ICL

AVX512FP16

在 x86::Microsoft Visual C/C++ 上#

名称

隐含

收集

FMA3

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C AVX2

AVX2

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3

AVX512F

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512CD AVX512_SKX

AVX512CD

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512_SKX

AVX512_KNL

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD

AVX512ER AVX512PF

AVX512_KNM

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_KNL

AVX5124FMAPS AVX5124VNNIW AVX512VPOPCNTDQ

AVX512_SPR

SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_SKX AVX512_CLX AVX512_CNL AVX512_ICL

AVX512FP16

构建报告#

在大多数情况下,CPU 构建选项不会产生导致构建挂起的任何致命错误。构建日志中可能出现的多数错误充当严重警告,因为编译器缺少一些预期 CPU 功能。

因此,我们强烈建议您查看最终的报告日志,以了解启用了哪些 CPU 功能,哪些没有启用。

您可以在构建日志的末尾找到 CPU 优化的最终报告,以下是它在 x86_64/gcc 上的外观

########### EXT COMPILER OPTIMIZATION ###########
Platform      :
  Architecture: x64
  Compiler    : gcc

CPU baseline  :
  Requested   : 'min'
  Enabled     : SSE SSE2 SSE3
  Flags       : -msse -msse2 -msse3
  Extra checks: none

CPU dispatch  :
  Requested   : 'max -xop -fma4'
  Enabled     : SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_KNL AVX512_KNM AVX512_SKX AVX512_CLX AVX512_CNL AVX512_ICL
  Generated   :
              :
  SSE41       : SSE SSE2 SSE3 SSSE3
  Flags       : -msse -msse2 -msse3 -mssse3 -msse4.1
  Extra checks: none
  Detect      : SSE SSE2 SSE3 SSSE3 SSE41
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_arithmetic.dispatch.c
              : numpy/_core/src/umath/_umath_tests.dispatch.c
              :
  SSE42       : SSE SSE2 SSE3 SSSE3 SSE41 POPCNT
  Flags       : -msse -msse2 -msse3 -mssse3 -msse4.1 -mpopcnt -msse4.2
  Extra checks: none
  Detect      : SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42
              : build/src.linux-x86_64-3.9/numpy/_core/src/_simd/_simd.dispatch.c
              :
  AVX2        : SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C
  Flags       : -msse -msse2 -msse3 -mssse3 -msse4.1 -mpopcnt -msse4.2 -mavx -mf16c -mavx2
  Extra checks: none
  Detect      : AVX F16C AVX2
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_arithm_fp.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_arithmetic.dispatch.c
              : numpy/_core/src/umath/_umath_tests.dispatch.c
              :
  (FMA3 AVX2) : SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C
  Flags       : -msse -msse2 -msse3 -mssse3 -msse4.1 -mpopcnt -msse4.2 -mavx -mf16c -mfma -mavx2
  Extra checks: none
  Detect      : AVX F16C FMA3 AVX2
              : build/src.linux-x86_64-3.9/numpy/_core/src/_simd/_simd.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_exponent_log.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_trigonometric.dispatch.c
              :
  AVX512F     : SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2
  Flags       : -msse -msse2 -msse3 -mssse3 -msse4.1 -mpopcnt -msse4.2 -mavx -mf16c -mfma -mavx2 -mavx512f
  Extra checks: AVX512F_REDUCE
  Detect      : AVX512F
              : build/src.linux-x86_64-3.9/numpy/_core/src/_simd/_simd.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_arithm_fp.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_arithmetic.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_exponent_log.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_trigonometric.dispatch.c
              :
  AVX512_SKX  : SSE SSE2 SSE3 SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD
  Flags       : -msse -msse2 -msse3 -mssse3 -msse4.1 -mpopcnt -msse4.2 -mavx -mf16c -mfma -mavx2 -mavx512f -mavx512cd -mavx512vl -mavx512bw -mavx512dq
  Extra checks: AVX512BW_MASK AVX512DQ_MASK
  Detect      : AVX512_SKX
              : build/src.linux-x86_64-3.9/numpy/_core/src/_simd/_simd.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_arithmetic.dispatch.c
              : build/src.linux-x86_64-3.9/numpy/_core/src/umath/loops_exponent_log.dispatch.c
CCompilerOpt.cache_flush[804] : write cache to path -> /home/seiko/work/repos/numpy/build/temp.linux-x86_64-3.9/ccompiler_opt_cache_ext.py

########### CLIB COMPILER OPTIMIZATION ###########
Platform      :
  Architecture: x64
  Compiler    : gcc

CPU baseline  :
  Requested   : 'min'
  Enabled     : SSE SSE2 SSE3
  Flags       : -msse -msse2 -msse3
  Extra checks: none

CPU dispatch  :
  Requested   : 'max -xop -fma4'
  Enabled     : SSSE3 SSE41 POPCNT SSE42 AVX F16C FMA3 AVX2 AVX512F AVX512CD AVX512_KNL AVX512_KNM AVX512_SKX AVX512_CLX AVX512_CNL AVX512_ICL
  Generated   : none

每个 build_extbuild_clib 都有一个单独的报告,包括几个部分,每个部分都有几个值,表示以下内容

平台:

  • 架构: 目标 CPU 的架构名称。它应该是以下之一:x86x64ppc64ppc64learmhfaarch64s390xunknown

  • 编译器: 编译器名称。它应该是以下之一:gcc、clang、msvc、icc、iccw 或类 Unix。

CPU 基线:

  • 请求: 对 cpu-baseline 的特定功能和选项,按原样。

  • 已启用: 最终启用的 CPU 功能集。

  • 标志: 在编译过程中用于所有 NumPy C/C++ 源代码的编译器标志,除了用于生成已调度功能的二进制对象的临时源代码之外。

  • 额外检查: 一系列内部检查,这些检查会激活与已启用功能相关的某些功能或内在函数,在开发 SIMD 内核时用于调试。

CPU 调度:

  • 请求: 对 cpu-dispatch 的特定功能和选项,按原样。

  • 已启用: 最终启用的 CPU 功能集。

  • 已生成: 在此属性的下一行的开头,将以多个部分的形式显示已为其生成优化的功能,每个部分具有类似的属性,如下所述

    • 一个或多个调度功能: 隐含的 CPU 功能。

    • 标志: 用于这些功能的编译器标志。

    • 额外检查: 与基线类似,但针对这些调度功能。

    • 检测: 一组需要在运行时检测的 CPU 功能,以便执行生成的优化。

    • 出现在上述属性之后并以单独一行上的“:”结尾的行表示定义生成优化的 c/c++ 源代码的路径。

运行时调度#

导入 NumPy 会触发对可调度功能集中的可用 CPU 功能进行扫描。可以通过将环境变量 NPY_DISABLE_CPU_FEATURES 设置为要禁用的功能的逗号、制表符或空格分隔列表来进一步限制此扫描。如果解析失败或功能未启用,这将引发错误。例如,在 x86_64 上,这将禁用 AVX2FMA3

NPY_DISABLE_CPU_FEATURES="AVX2,FMA3"

如果功能不可用,将发出警告。

跟踪调度功能#

可以通过 Python 函数 numpy.lib.introspect.opt_func_info 发现为不同优化功能启用了哪些 CPU 目标。此函数提供了使用两个可选参数应用过滤器的灵活性:一个用于细化函数名称,另一个用于指定签名中的数据类型。

例如

 >> func_info = numpy.lib.introspect.opt_func_info(func_name='add|abs', signature='float64|complex64')
 >> print(json.dumps(func_info, indent=2))
 {
   "absolute": {
     "dd": {
       "current": "SSE41",
       "available": "SSE41 baseline(SSE SSE2 SSE3)"
     },
     "Ff": {
       "current": "FMA3__AVX2",
       "available": "AVX512F FMA3__AVX2 baseline(SSE SSE2 SSE3)"
     },
     "Dd": {
       "current": "FMA3__AVX2",
       "available": "AVX512F FMA3__AVX2 baseline(SSE SSE2 SSE3)"
     }
   },
   "add": {
     "ddd": {
       "current": "FMA3__AVX2",
       "available": "FMA3__AVX2 baseline(SSE SSE2 SSE3)"
     },
     "FFF": {
       "current": "FMA3__AVX2",
       "available": "FMA3__AVX2 baseline(SSE SSE2 SSE3)"
     }
  }
}