CPU 构建选项#

描述#

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

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

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

    注意

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

  • cpu-dispatch:调度程序的附加 CPU 功能集。

    默认值为 max -xop -fma4,它启用所有 CPU 功能,但 AMD 遗留功能除外(对于 X86)。

    注意

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

这些选项可以通过构建前端(例如 pipbuild)将安装参数传递给 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特性

    架构

    隐含

    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特性。

  • 运算符-/+:移除或添加特性,与选项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"
    
  • 如果通过环境变量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会跳过任何指定的基线特性,还会跳过目标平台或编译器不支持的任何特性,而不会引发致命错误。

最终,您应该始终通过构建日志检查最终报告,以验证已启用的特性。有关更多详细信息,请参见构建报告

平台差异#

某些特殊情况迫使我们在处理某些编译器或架构时将某些特性链接在一起,导致无法单独构建它们。

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

架构兼容性

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