CPU Build Options#

Обзор#

NumPy предоставляет параметры конфигурации для оптимизации производительности на основе возможностей процессора. Эти параметры позволяют указать, какие функции процессора поддерживать, балансируя производительность, совместимость и размер бинарного файла. Этот документ объясняет, как эффективно использовать эти параметры на различных архитектурах процессоров.

Ключевые параметры конфигурации#

NumPy использует несколько опций сборки для управления оптимизациями CPU:

  • cpu-baseline: Минимальный набор функций процессора, необходимый для работы скомпилированного NumPy.

    • По умолчанию: min (обеспечивает совместимость на широком спектре платформ)

    • Если ваш целевой процессор не поддерживает все указанные базовые функции, NumPy не загрузится с ошибкой времени выполнения Python

  • cpu-baseline-detect: управляет определением базовой конфигурации процессора на основе флагов компилятора. Значение по умолчанию: auto который позволяет обнаружить, если -march= или аналогичный флаг компилятора используется. Другие возможные значения: enabled и disabled для соответствующего безусловного включения или отключения.

  • cpu-dispatch: Дополнительные функции процессора, для которых будут сгенерированы оптимизированные пути кода.

    • По умолчанию: max (включает все доступные оптимизации)

    • Во время выполнения NumPy автоматически выберет самый быстрый доступный путь кода на основе возможностей вашего процессора

  • disable-optimization: Полностью отключает все оптимизации ЦП.

    • По умолчанию: 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 numpy.ma.MaskedArray.round Группы CPU, функции, или специальные опции которые выполняют определённые действия. Следующие разделы подробно описывают эти опции.

Типичные сценарии использования#

Сборка только для локального использования#

При сборке только для вашей машины и без планов распространения:

python -m build --wheel -Csetup-args=-Dcpu-baseline="native" -Csetup-args=-Dcpu-dispatch="none"

Это автоматически обнаруживает и использует все доступные функции процессора на вашем компьютере.

Примечание

Фатальная ошибка будет вызвана, если 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 также.

Нацеливание на старые процессоры#

На x86-64, по умолчанию базовый уровень установлен на min который соответствует X86_V2. Это не подходит для старых процессоров (до 2009 года) или старых виртуальных машин. Чтобы решить эту проблему, установите базовый уровень на none:

python -m build --wheel -Csetup-args=-Dcpu-baseline="none"

Это создаст сборку, совместимую со всеми x86 CPU, но без ручных оптимизаций или SIMD путей кода для базовой линии. Сборка будет полагаться только на диспетчеризированные пути кода для оптимизации.

Нацеливание на более новые процессоры#

Повышение базового уровня улучшает производительность по двум основным причинам:

  1. Диспетчеризованные ядра не покрывают все пути кода

  2. Более высокий базовый уровень приводит к меньшему размеру бинарного файла, так как компилятор не будет генерировать пути кода для исключённых диспетчеризованных функций

Для процессоров с 2015 года и новее, установка базового уровня на X86_V3 может быть подходящим:

python -m build --wheel -Csetup-args=-Dcpu-baseline="min+X86_V3"

Поддерживаемые функции ЦП по архитектуре#

NumPy поддерживает оптимизированные пути кода для нескольких архитектур CPU. Ниже приведены поддерживаемые группы функций для каждой архитектуры. Имя группы функций может использоваться в параметрах сборки cpu-baseline и cpu-dispatch.

X86#

Name

Подразумевает

Включает

X86_V2

SSE SSE2 SSE3 SSSE3 SSE4_1 SSE4_2 POPCNT CX16 LAHF

X86_V3

X86_V2

AVX AVX2 FMA3 BMI BMI2 LZCNT F16C MOVBE

X86_V4

X86_V3

AVX512F AVX512CD AVX512VL AVX512BW AVX512DQ

AVX512_ICL

X86_V4

AVX512VBMI AVX512VBMI2 AVX512VNNI AVX512BITALG AVX512VPOPCNTDQ AVX512IFMA VAES GFNI VPCLMULQDQ

AVX512_SPR

AVX512_ICL

AVX512FP16

Эти группы соответствуют поколениям процессоров:

  • X86_V2: микроархитектуры x86-64-v2 (ЦП с 2009 года)

  • X86_V3: x86-64-v3 микроархитектуры (процессоры с 2015 года)

  • X86_V4: микропроцессорные архитектуры x86-64-v4 (процессоры с поддержкой AVX-512)

  • AVX512_ICL: Intel Ice Lake и аналогичные процессоры

  • AVX512_SPR: Intel Sapphire Rapids и более новые процессоры

Примечание

На 32-битном x86, cx16 исключён из X86_V2.

На IBM/POWER big-endian#

Name

Подразумевает

VSX

VSX2

VSX

VSX3

VSX VSX2

VSX4

VSX VSX2 VSX3

На IBM/POWER с прямым порядком байтов#

Name

Подразумевает

VSX

VSX2

VSX2

VSX

VSX3

VSX VSX2

VSX4

VSX VSX2 VSX3

На ARMv7/A32#

Name

Подразумевает

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#

Name

Подразумевает

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)#

Name

Подразумевает

VX

VXE

VX

VXE2

VX VXE

На RISCV64#

Name

Подразумевает

RVV

Специальные опции#

Помимо конкретных названий функций, вы можете использовать эти специальные значения:

NONE#

Отключает все функции (эквивалентно пустой строке).

NATIVE#

Включает все функции, поддерживаемые процессором хоста.

DETECT#

Обнаруживает функции, включенные компилятором. Эта опция по умолчанию добавляется к cpu-baseline if -march, -mcpu, -xhost, или /QxHost установлена в переменной окружения CFLAGS если только cpu-baseline-detect является disabled.

MIN#

Включает минимальные функции ЦП для каждой архитектуры:

Для Arch

Подразумевает

x86 (32-битный)

X86_V2

x86-64

X86_V2

IBM/POWER (big-endian)

NONE

IBM/POWER (little-endian)

VSX VSX2

ARMv7/ARMHF

NONE

ARMv8/AArch64

NEON NEON_FP16 NEON_VFPV4 ASIMD

IBM/ZSYSTEM(S390X)

NONE

riscv64

NONE

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"

Использование и Поведения#

Регистронезависимость#

Функции и опции процессора нечувствительны к регистру:

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", он исключит X86_V4 и его подразумеваемые возможности X86_V2 и X86_V3 из cpu-dispatch признаков.

Обнаружение во время компиляции#

Указание признаков для cpu-dispatch или cpu-baseline не включает их явно. Функции определяются во время компиляции, и максимально доступные функции на основе ваших указанных опций будут включены в соответствии с поддержкой инструментария и платформы.

Это обнаружение происходит путём проверки доступности функций в компиляторе через исходные файлы времени компиляции, содержащие общие встроенные функции для указанных возможностей. Если и компилятор, и ассемблер поддерживают функцию, она будет включена.

Например, если вы укажете cpu-dispatch="AVX512_ICL" но ваш компилятор не поддерживает это, функция будет исключена из сборки. Однако любые подразумеваемые функции всё равно будут включены, если они поддерживаются.

Различия платформ#

Некоторые исключительные условия вынуждают нас связывать некоторые функции вместе, когда дело касается определённых компиляторов или архитектур, что делает невозможным их отдельную сборку.

Эти условия можно разделить на две части следующим образом:

Архитектурная совместимость

Необходимость согласования определенных функций процессора, которые гарантированно поддерживаются последовательными поколениями одной архитектуры, некоторые случаи:

  • На ppc64le VSX(ISA 2.06) и VSX2(ISA 2.07) оба подразумевают друг друга, поскольку первое поколение, поддерживающее режим little-endian, это 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 компилятором.

Поэтому мы настоятельно рекомендуем проверять итоговый журнал отчёта, чтобы знать, какие функции процессора включены, а какие нет.

Вы можете найти окончательный отчет об оптимизациях ЦП, отслеживая журнал сборки meson, и вот как это выглядит на 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 запускает сканирование доступных функций ЦП из набора диспетчеризуемых функций. Вы можете ограничить это сканирование, установив переменную окружения NPY_DISABLE_CPU_FEATURES в список функций, разделённых запятыми, табуляцией или пробелами, для отключения.

Например, на x86_64 это отключит X86_V4:

NPY_DISABLE_CPU_FEATURES="X86_V4"

Это вызовет ошибку, если разбор не удастся или если функция не была включена через cpu-dispatch опция сборки. Если функция поддерживается сборкой, но недоступна на текущем процессоре, будет выдано предупреждение.

Отслеживание диспетчеризованных функций#

Вы можете узнать, какие целевые CPU включены для различных оптимизированных функций, используя функцию Python numpy.lib.introspect.opt_func_info.

Эта функция предлагает два дополнительных аргумента для фильтрации результатов:

  1. func_name - Для уточнения имен функций

  2. 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)"
    }
  }
}