CPU 构建选项#
概述#
NumPy 提供配置选项以根据 CPU 功能优化性能。这些选项允许您指定要支持的 CPU 功能,平衡性能、兼容性和二进制大小。本文档解释了如何在各种 CPU 架构中有效使用这些选项。
关键配置选项#
NumPy 使用多个构建选项来控制 CPU 优化。
cpu-baseline:编译的 NumPy 运行所需的最低 CPU 功能集。默认值:
min(提供跨广泛平台的兼容性)如果您的目标 CPU 不支持所有指定的基线功能,NumPy 将会因 Python 运行时错误而无法加载。
cpu-baseline-detect:控制基于编译器标志的 CPU 基线检测。默认值为auto,如果在编译时使用了-march=或类似的编译器标志,则会启用检测。其他可能的值是enabled和disabled,分别无条件地启用或禁用它。cpu-dispatch:将生成优化代码路径的额外 CPU 功能。默认值:
max(启用所有可用优化)运行时,NumPy 会根据您的 CPU 功能自动选择最快的可用代码路径。
disable-optimization:完全禁用所有 CPU 优化。默认值:
false(启用优化)当设置为
true时,将禁用所有 CPU 优化的代码,包括调度、SIMD 和循环展开。对于调试、测试或优化可能导致问题的环境非常有用。
这些选项通过 meson-python 参数在构建时指定。
pip install . -Csetup-args=-Dcpu-baseline="min" -Csetup-args=-Dcpu-dispatch="max"
# or through spin
spin build -- -Dcpu-baseline="min" -Dcpu-dispatch="max"
cpu-baseline 和 cpu-dispatch 可以设置为特定的 CPU 组、功能,或执行特定操作的 特殊选项。以下各节将详细介绍这些选项。
常见用法场景#
仅为本地使用进行构建#
仅为您的计算机构建,且不打算分发时。
python -m build --wheel -Csetup-args=-Dcpu-baseline="native" -Csetup-args=-Dcpu-dispatch="none"
此选项会自动检测并使用您计算机上的所有可用 CPU 功能。
注意
如果主机平台不支持 native,则会引发致命错误。
排除特定功能#
您可能希望从调度功能中排除某些 CPU 功能。
# For x86-64: exclude all AVX-512 features
python -m build --wheel -Csetup-args=-Dcpu-dispatch="max -X86_V4"
# For ARM64: exclude SVE
python -m build --wheel -Csetup-args=-Dcpu-dispatch="max -SVE"
注意
排除某个功能也会排除该功能所隐含的任何后续功能。例如,排除 X86_V4 会同时排除 AVX512_ICL 和 AVX512_SPR。
针对较旧的 CPU#
在 x86-64 上,默认基线设置为 min,它映射到 X86_V2。这不适用于较旧的 CPU(2009 年之前)或旧的虚拟机。要解决此问题,请将基线设置为 none。
python -m build --wheel -Csetup-args=-Dcpu-baseline="none"
这将创建一个与所有 x86 CPU 兼容的构建,但基线没有任何手动优化或 SIMD 代码路径。构建将仅依赖于调度代码路径进行优化。
针对较新的 CPU#
提高基线性能主要有两个原因:
调度内核不覆盖所有代码路径。
更高的基线导致更小的二进制文件大小,因为编译器不会为排除的调度功能生成代码路径。
对于 2015 年及更新的 CPU,将基线设置为 X86_V3 可能就足够了。
python -m build --wheel -Csetup-args=-Dcpu-baseline="min+X86_V3"
按架构支持的 CPU 功能#
NumPy 支持多种 CPU 架构的优化代码路径。以下是每种架构支持的功能组。功能组的名称可用于构建选项 cpu-baseline 和 cpu-dispatch。
X86#
名称 |
隐含 |
包含 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
这些组对应于 CPU 代。
X86_V2:x86-64-v2 微架构(2009 年以来的 CPU)X86_V3:x86-64-v3 微架构(2015 年以来的 CPU)X86_V4:x86-64-v4 微架构(支持 AVX-512 的 CPU)AVX512_ICL:Intel Ice Lake 及类似 CPUAVX512_SPR:Intel Sapphire Rapids 及更新的 CPU
注意
在 32 位 x86 上,cx16 已从 X86_V2 中排除。
在 IBM/POWER 大端序#
名称 |
隐含 |
|---|---|
|
|
|
|
|
|
|
|
在 IBM/POWER 小端序#
名称 |
隐含 |
|---|---|
|
|
|
|
|
|
|
|
在 ARMv7/A32#
名称 |
隐含 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在 ARMv8/A64#
名称 |
隐含 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在 IBM/ZSYSTEM(S390X)#
名称 |
隐含 |
|---|---|
|
|
|
|
|
|
在 RISCV64#
名称 |
隐含 |
|---|---|
|
特殊选项#
除了特定的功能名称外,您还可以使用这些特殊值:
NONE#
启用所有功能(等同于空字符串)。
NATIVE#
启用主机 CPU 支持的所有功能。
DETECT#
检测编译器启用的功能。如果环境变量 CFLAGS 中设置了 -march、-mcpu、-xhost 或 /QxHost,则此选项将默认附加到 cpu-baseline,除非 cpu-baseline-detect 被设置为 disabled。
MIN#
为每种架构启用最低 CPU 功能。
对于架构 |
隐含 |
|---|---|
x86(32 位) |
|
x86-64 |
|
IBM/POWER(大端序) |
|
IBM/POWER(小端序) |
|
ARMv7/ARMHF |
|
ARMv8/AArch64 |
|
IBM/ZSYSTEM(S390X) |
|
riscv64 |
|
MAX#
启用编译器和平台支持的所有功能。
运算符(-/+)#
移除或添加特定功能,与 MAX、MIN 和 NATIVE 结合使用非常方便。
添加功能(
+)会包含所有隐含功能。移除功能(
-)会排除所有隐含已移除功能的后续功能。
示例
python -m build --wheel -Csetup-args=-Dcpu-dispatch="max-X86_V4"
python -m build --wheel -Csetup-args=-Dcpu-baseline="min+X86_V4"
用法和行为#
不区分大小写#
CPU 功能和选项不区分大小写。
python -m build --wheel -Csetup-args=-Dcpu-dispatch="X86_v4"
混合跨架构的功能#
您可以混合使用不同架构的功能。
python -m build --wheel -Csetup-args=-Dcpu-baseline="X86_V4 VSX4 SVE"
顺序无关性#
指定功能的顺序无关紧要。
python -m build --wheel -Csetup-args=-Dcpu-dispatch="SVE X86_V4 x86_v3"
分隔符#
您可以使用空格或逗号作为分隔符。
# All of these are equivalent
python -m build --wheel -Csetup-args=-Dcpu-dispatch="X86_V2 X86_V4"
python -m build --wheel -Csetup-args=-Dcpu-dispatch=X86_V2,X86_V4
功能组合#
选项中指定的功能会自动与所有隐含功能组合。
python -m build --wheel -Csetup-args=-Dcpu-baseline=X86_V4
等同于
python -m build --wheel -Csetup-args=-Dcpu-baseline="X86_V2 X86_V3 X86_V4"
基线重叠#
在 cpu-baseline 中指定的功能将从 cpu-dispatch 功能中排除,以及它们所隐含的功能,但不会排除隐含它们的功能的后续功能。
例如,如果您指定 cpu-baseline="X86_V4",它将从 cpu-dispatch 功能中排除 X86_V4 及其隐含功能 X86_V2 和 X86_V3。
编译时检测#
将功能指定给 cpu-dispatch 或 cpu-baseline 并不会显式启用它们。功能在编译时进行检测,并根据工具链和平台支持,根据您指定的选项启用最大可用功能。
此检测通过包含指定功能通用内在函数的编译时源文件,在编译器中测试功能可用性来完成。如果编译器和汇编器都支持该功能,则会启用它。
例如,如果您指定 cpu-dispatch="AVX512_ICL" 但您的编译器不支持,该功能将在构建中被排除。但是,如果其他隐含功能受支持,它们仍会被启用。
平台差异#
对于某些编译器或架构,一些特殊情况迫使我们将某些功能链接在一起,导致无法单独构建它们。
这些情况可分为两部分,如下所示:
架构兼容性
需要对同一架构的连续代 CPU 所确保支持的某些 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 功能,以确定相互隐含的功能。
构建报告#
在大多数情况下,CPU 构建选项不会产生导致构建中断的致命错误。构建日志中出现的大多数错误是由于编译器缺少某些预期的 CPU 功能而发出的警告。
因此,我们强烈建议检查最终报告日志,以了解启用了哪些 CPU 功能以及哪些未启用。
您可以通过跟踪 meson 构建日志找到 CPU 优化报告,以下是 x86_64/gcc 上的示例:
Test features "X86_V2" : Supported
Test features "X86_V3" : Supported
Test features "X86_V4" : Supported
Test features "AVX512_ICL" : Supported
Test features "AVX512_SPR" : Supported
Configuring npy_cpu_dispatch_config.h using configuration
Message:
CPU Optimization Options
baseline:
Requested : min
Enabled : X86_V2
dispatch:
Requested : max
Enabled : X86_V3 X86_V4 AVX512_ICL AVX512_SPR
Generating multi-targets for "_umath_tests.dispatch.h"
Enabled targets: X86_V3, baseline
Generating multi-targets for "argfunc.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "x86_simd_argsort.dispatch.h"
Enabled targets: X86_V4, X86_V3
Generating multi-targets for "x86_simd_qsort.dispatch.h"
Enabled targets: X86_V4, X86_V3
Generating multi-targets for "x86_simd_qsort_16bit.dispatch.h"
Enabled targets: AVX512_SPR, AVX512_ICL
Generating multi-targets for "highway_qsort.dispatch.h"
Enabled targets:
Generating multi-targets for "highway_qsort_16bit.dispatch.h"
Enabled targets:
Generating multi-targets for "loops_arithm_fp.dispatch.h"
Enabled targets: X86_V3, baseline
Generating multi-targets for "loops_arithmetic.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "loops_comparison.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "loops_exponent_log.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "loops_hyperbolic.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "loops_logical.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "loops_minmax.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "loops_modulo.dispatch.h"
Enabled targets: baseline
Generating multi-targets for "loops_trigonometric.dispatch.h"
Enabled targets: X86_V4, X86_V3, baseline
Generating multi-targets for "loops_umath_fp.dispatch.h"
Enabled targets: X86_V4, baseline
Generating multi-targets for "loops_unary.dispatch.h"
Enabled targets: X86_V4, baseline
Generating multi-targets for "loops_unary_fp.dispatch.h"
Enabled targets: baseline
Generating multi-targets for "loops_unary_fp_le.dispatch.h"
Enabled targets: baseline
Generating multi-targets for "loops_unary_complex.dispatch.h"
Enabled targets: X86_V3, baseline
Generating multi-targets for "loops_autovec.dispatch.h"
Enabled targets: X86_V3, baseline
Generating multi-targets for "loops_half.dispatch.h"
Enabled targets: AVX512_SPR, X86_V4, baseline
WARNING: Project targets '>=1.5.2' but uses feature deprecated since '1.3.0': Source file src/umath/svml/linux/avx512/svml_z0_acos_d_la.s in the 'objects' kwarg is not an object..
Generating multi-targets for "_simd.dispatch.h"
Enabled targets: X86_V3, X86_V4, baseline
运行时调度#
导入 NumPy 会触发对可用 CPU 功能的扫描,这些功能来自可调度功能集。您可以通过将环境变量 NPY_DISABLE_CPU_FEATURES 设置为逗号、制表符或空格分隔的功能列表来禁用某些功能。
例如,在 x86_64 上,这将禁用 X86_V4。
NPY_DISABLE_CPU_FEATURES="X86_V4"
如果解析失败或功能未通过 cpu-dispatch 构建选项启用,则会引发错误。如果功能已通过构建支持但在当前 CPU 上不可用,则会发出警告。
跟踪调度函数#
您可以使用 Python 函数 numpy.lib.introspect.opt_func_info 来发现不同优化函数启用的 CPU 目标。
此函数提供两个可选参数用于过滤结果:
func_name- 用于细化函数名称。signature- 用于指定签名中的数据类型。
例如:
>> 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": "baseline(X86_V2)",
"available": "baseline(X86_V2)"
},
"Ff": {
"current": "X86_V3",
"available": "X86_V3 baseline(X86_V2)"
},
"Dd": {
"current": "X86_V3",
"available": "X86_V3 baseline(X86_V2)"
}
},
"add": {
"ddd": {
"current": "X86_V3",
"available": "X86_V3 baseline(X86_V2)"
},
"FFF": {
"current": "X86_V3",
"available": "X86_V3 baseline(X86_V2)"
}
}
}