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 features 或一组功能,它们收集几个功能或执行一系列过程的 special options .

要自定义 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 至少支持 AVX , F16C 功能,你可以使用:

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 -avx512_spr"

支持的功能#

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

备注

以下功能可能不被所有编译器支持,而且当涉及到 AVX512 , AVX2FMA3 等功能时,某些编译器可能会产生不同的隐含功能集. 更多详情请参见 平台差异 .

在 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-/+ :删除或添加特性,与选项 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 会转义任何指定的基线特性,并转义目标平台或编译器不支持的任何特性,而不会引发致命错误.

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

平台差异#

某些特殊情况迫使我们在涉及某些编译器或体系结构时将某些特性链接在一起,从而导致无法单独构建它们.

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

架构兼容性

需要对齐同一体系结构的后续生成保证支持的某些 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 Compiler#

名称

暗示

聚集

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

平台:

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

  • Compiler : 编译器名称.它应该是 gcc,clang,msvc,icc,iccw 或类 Unix 中的一种.

CPU 基准:

  • Requested : cpu-baseline 的具体特性和选项,与原样相同.

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

  • Flags : 在编译期间用于所有 NumPy C/C++ 源代码的编译器标志,但用于生成已调度特性的二进制对象的临时源除外.

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

CPU 调度:

  • Requested : cpu-dispatch 的具体特性和选项,与原样相同.

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

  • Generated : 在此属性的下一行开始处,将以多个具有类似属性的部分的形式显示已为其生成优化的特性,解释如下:

    • One or multiple dispatched feature : 隐含的 CPU 特性.

    • Flags : 用于这些特性的编译器标志.

    • Extra checks : 类似于基线,但用于这些调度的特性.

    • Detect : 需要在运行时检测的 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)"
     }
  }
}