CPU 构建选项#
描述#
以下选项主要用于更改针对特定 CPU 功能的优化的默认行为
cpu-baseline
: 最小的 CPU 功能集。默认值为
min
,它提供了可以在处理器系列中广泛的平台上安全运行的最小 CPU 功能。注意
在运行时,如果 NumPy 模块无法在目标 CPU 上找到任何指定的 CPU 功能,则加载模块将失败(引发 Python 运行时错误)。
cpu-dispatch
: 派遣的 CPU 功能集。默认值为
max -xop -fma4
,它启用了所有 CPU 功能,除了 AMD 的遗留功能(在 X86 的情况下)。注意
在运行时,NumPy 模块将跳过目标 CPU 中不可用的任何指定功能。
这些选项在构建时可以通过向 meson-python 传递设置参数来访问,这些参数通过构建前端(例如 pip
或 build
)传递。它们接受一组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 现在都至少支持 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
、AVX2
和 FMA3
等功能时,某些编译器可能会产生不同的隐含功能集。有关更多详细信息,请参见平台差异。
在 x86 上#
名称 |
隐含 |
收集 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在 IBM/POWER 大端上#
名称 |
隐含 |
---|---|
|
|
|
|
|
|
|
|
在 IBM/POWER 小端上#
名称 |
隐含 |
---|---|
|
|
|
|
|
|
|
|
在 ARMv7/A32 上#
名称 |
隐含 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在 ARMv8/A64 上#
名称 |
隐含 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
在 IBM/ZSYSTEM(S390X)#
名称 |
隐含 |
---|---|
|
|
|
|
|
|
特殊选项#
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
、MIN
和NATIVE
选项中很有用。
行为#
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** 的编译器没有为 AVX2
和 FMA3
提供单独的标志,这很有意义,因为所有带有 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_ext
和 build_clib
都有一个单独的报告,包括几个部分,每个部分都有几个值,表示以下内容
平台:
架构: 目标 CPU 的架构名称。它应该是以下之一:
x86
、x64
、ppc64
、ppc64le
、armhf
、aarch64
、s390x
或unknown
。编译器: 编译器名称。它应该是以下之一: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
上,这将禁用 AVX2
和 FMA3
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)"
}
}
}