CPU 构建选项#

描述#

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

  • cpu-baseline: 所需的最小CPU特性集.

    默认值是 min,它提供了在处理器家族中广泛平台上的安全运行的最低CPU特性.

    备注

    在运行时,如果目标CPU不支持任何指定的功能,NumPy模块将无法加载(引发Python运行时错误).

  • cpu-dispatch: 额外CPU特性的分派集合.

    默认值是 max -xop -fma4,它启用了所有 CPU 特性,除了 AMD 的遗留特性(在 X86 情况下).

    备注

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

这些选项在构建时可以通过传递设置参数给构建前端(例如,``pip`` 或 build)的 meson-python 来访问.它们接受一组 CPU 特性 或特性组,这些特性组收集了几个特性,或者 特殊选项 执行一系列程序.

要自定义 CPU/构建选项:

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

快速开始#

一般来说,默认设置倾向于不强制使用某些可能在某些旧处理器上不可用的CPU特性.提高基线特性的上限通常会提高性能,并且还可能减小二进制文件的大小.

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

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

并且我不打算将构建导出给其他用户或在不同于主机的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 又称 AARCH64

    NEON NEON_FP16 NEON_VFPV4 ASIMD

    IBM/ZSYSTEM(S390X)

    NONE

  • MAX: 通过编译器和平台启用所有支持的CPU特性.

  • Operators-/+: 移除或添加功能,与选项 MAX, MINNATIVE 一起使用非常有用.

行为#

  • 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"
    
  • 如果通过环境变量 CFLAGS 启用了编译器原生标志 -march=native-xHost/QxHost,则 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 会避开任何指定的基线特性,并且还会避开目标平台或编译器不支持的任何特性,而不会引发致命错误.

最终,你应该始终通过构建日志检查最终报告,以验证启用的功能.更多详情请参见 构建报告.

平台差异#

某些特殊情况迫使我们在涉及到某些编译器或架构时将某些功能链接在一起,导致无法单独构建它们.

这些条件可以分为两部分,如下所示:

Architectural compatibility

需要对齐某些 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"

备注

请仔细查看 支持的功能,以确定相互关联的功能.

Compilation compatibility

一些编译器不提供对所有CPU特性的独立支持.例如,**Intel**的编译器不提供``AVX2``和``FMA3``的分离标志,因为所有带有``AVX2``的Intel CPU也支持``FMA3``,这是有道理的,但这种方法与其他**x86** CPU(如**AMD**或**VIA**)不兼容.

例如:

# 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 ,每个都有一个单独的报告,其中包括几个部分,每个部分有几个值,代表以下内容:

Platform:

  • 架构: 目标CPU的架构名称.它应该是以下之一:x86, x64, ppc64, ppc64le, armhf, aarch64, s390xunknown.

  • 编译器: 编译器名称.它应该是 gcc、clang、msvc、icc、iccw 或类 Unix 系统之一.

CPU baseline:

  • 请求的: 对 cpu-baseline 的具体功能和选项保持不变.

  • 启用: 启用的CPU特性最终集合.

  • 标志: 在编译期间用于所有NumPy C/C++源文件的编译器标志,除了用于生成分派功能二进制对象的临时源文件.

  • 额外检查: 激活某些功能或与启用功能相关的内在函数的内部检查列表,在开发SIMD内核时用于调试非常有用.

CPU dispatch:

  • 请求的: 对 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)"
     }
  }
}