DSP-инструкции Armv7E-M
Цифровой фильтр — это в основном умножения с накоплением: отсчёт на коэффициент, плюс к сумме. У Cortex-M4 есть команды, которые делают два таких умножения 16 × 16 бит за раз и складывают байты и полуслова параллельно. Это DSP-расширение архитектуры Armv7-M.
Обновлено Редакция GAW
DSP-инструкции — команды необязательного DSP-расширения архитектуры Armv7-M. Реализация архитектуры с этим расширением называется Armv7E-M; такие команды есть, например, у ядра Cortex-M4. Расширение добавляет к набору Thumb-2 команды с насыщением, умножения 16 × 16 бит с накоплением и SIMD-команды, которые обрабатывают сразу два полуслова или четыре байта одного регистра (Armv7-M ARM, разд. A1.3). Arm в руководстве по Cortex-M4 перечисляет их среди главных возможностей ядра: однотактные и SIMD-умножения с накоплением и арифметика с насыщением (DUI 0553B, разд. 1.1); у Cortex-M3 в списке команд их нет, из команд насыщения там только SSAT и USAT (DUI 0552A, разд. 3.1 и 3.7).
Группы команд
| Группа | Примеры | Что делает |
|---|---|---|
| Умножение с накоплением | SMLAD, SMLALD, SMLABB | SMLAD: 32 = 32 + 16 × 16 + 16 × 16; SMLALD: то же с 64-битным аккумулятором; SMLABB: одно произведение 16 × 16 плюс 32-битный аккумулятор (A7.7.136, A7.7.137, A7.7.140) |
| Умножение слова на полуслово | SMLAWB, SMULWB | старшие 32 бита произведения 32 × 16 |
| Параллельное сложение | SADD16, UADD8, QADD16 | два полуслова или четыре байта сразу |
| Насыщение | QADD, QSUB, SSAT16 | результат не переходит через границу диапазона |
| Упаковка | PKHBT, SXTB16 | сборка и расширение полуслов и байтов |
По табл. A4-6 — A4-14 Armv7-M ARM. Параллельные команды собраны из префикса и операции: префиксы S и U — знаковая и беззнаковая арифметика по модулю, Q и UQ — с насыщением, SH и UH — с делением результата пополам; операции — ADD16, SUB16, ASX, SAX, ADD8, SUB8. Всего 36 сочетаний. SIMD-команды пишут во флаги GE[3:0] результат по каждой части, и команда SEL по этим флагам собирает итог из байтов двух регистров.
SMLAD и фильтры
SMLAD берёт два регистра как пары 16-битных знаковых чисел, перемножает младшие половины и старшие половины и прибавляет оба произведения к 32-битному аккумулятору. Умножения переполниться не могут, а если переполнится сложение, ставится флаг Q (разд. A7.7.137). Если отсчёты и коэффициенты КИХ-фильтра хранятся в формате Q15 парами в 32-битных словах, одна команда SMLAD считает два отвода фильтра (наш вывод из определения команды). Отсюда выигрыш Cortex-M4 в обработке звука и сигналов датчиков по сравнению с Cortex-M3, которому на те же два отвода нужны отдельные умножения и сложения.
Как использовать
На C эти команды вызывают через встроенные функции CMSIS: __SMLAD(), __SADD16(), __QADD() и другие. В заголовке cmsis_gcc.h они определены только при __ARM_FEATURE_DSP == 1 — компилятор задаёт этот макрос для ядер с DSP-расширением, поэтому на Cortex-M3 такой код не соберётся. Базовые команды насыщения SSAT и USAT есть и без расширения — о них в термине «Арифметика с насыщением». Числа с плавающей точкой DSP-расширение не обрабатывает: это работа отдельного FPU.
Частые вопросы
Есть ли DSP-инструкции у Cortex-M3?
Нет. DSP-расширение необязательное, реализация архитектуры с ним называется Armv7E-M (Armv7-M ARM, разд. A1.3). В сводной таблице команд Cortex-M3 нет ни SMLAD, ни QADD, ни SIMD-сложений, а из команд насыщения есть только базовые SSAT и USAT (DUI 0552A, разд. 3.1 и 3.7); у Cortex-M4 весь набор есть (DUI 0553B). В CMSIS функции вроде __SMLAD определены лишь при __ARM_FEATURE_DSP == 1, так что на Cortex-M3 код с ними просто не соберётся.
Что делает команда SMLAD?
Берёт два 32-битных регистра как пары 16-битных знаковых чисел, перемножает младшие половины между собой и старшие между собой и прибавляет обе суммы к 32-битному аккумулятору — одной командой. Вариант SMLADX перед этим меняет местами половины второго операнда. Если сумма переполняет 32 бита, ставится флаг Q (Armv7-M ARM, разд. A7.7.137).
Нужно ли писать на ассемблере, чтобы использовать DSP-инструкции?
Нет. Заголовки CMSIS-Core дают встроенные функции __SMLAD, __SADD16, __QADD и другие: каждая разворачивается в одну команду ядра. Определены они только для ядер с DSP-расширением — при __ARM_FEATURE_DSP == 1 (cmsis_gcc.h), поэтому код с ними сразу показывает, что ему нужно ядро Armv7E-M.
Источники
- Arm. Armv7-M Architecture Reference Manual (ARM DDI 0403E.e, ID021621) — разд. A1.3: необязательное DSP-расширение добавляет в набор Thumb команды цифровой обработки сигналов, в том числе с насыщением и беззнаковые SIMD; реализация с ним называется Armv7E-M; разд. A2.3.2: флаг Q ставят SSAT, USAT и некоторые умножения DSP-расширения, флаги GE[3:0] (бит 19:16, только с DSP) — результаты по байтам и полусловам SIMD, их использует SEL; разд. A4.4.3, табл. A4-6 и A4-8: SMLABB… (32 = 32 + 16 × 16), SMLAD (32 = 32 + 16 × 16 + 16 × 16), SMLALD (64 = 64 + 16 × 16 + 16 × 16), SMLAWB (32 = 32 + 32 × 16), SMMLA, SMUAD, SMUSD, UMAAL (64 = 32 + 32 + 32 × 32); разд. A4.4.4, табл. A4-10, A4-11: SSAT16, USAT16, QADD, QSUB, QDADD, QDSUB; разд. A4.4.7, табл. A4-14: префиксы S, Q, SH, U, UQ, UH и операции ADD16, ASX, SAX, SUB16, ADD8, SUB8 — 36 сочетаний; разд. A7.7.137: SMLAD выполняет два знаковых умножения 16 × 16 и прибавляет их к 32-битному аккумулятору, X меняет полуслова второго операнда, при переполнении сложения ставит Q, умножения переполниться не могут
- Arm. CMSIS-Core cmsis_gcc.h, V5.4.1, 27 May 2021 (Apache-2.0) — функции __SADD16, __SMLAD, __SMLADX, __QADD и другие определены только при __ARM_FEATURE_DSP == 1; __SSAT и __USAT — команды для Armv7-M, Armv7E-M и Armv8-M Mainline, для остальных ядер — программная замена на C
- Arm. Cortex-M4 Devices Generic User Guide (ARM DUI 0553B, ID012616) — разд. 1.1: ядро с трёхступенчатым конвейером, необязательный FPU одинарной точности по IEEE 754, однотактные и SIMD-умножения и умножения с накоплением, арифметика с насыщением, аппаратное деление; бит 27 Q — флаг переполнения и насыщения DSP; разд. 3.6.4: SMLAD и SMLADX рассматривают операнды как четыре 16-битных полуслова; разд. 3.7: команды насыщения, в том числе QADD, QSUB, QDADD, QDSUB и SIMD-варианты
- Arm. Cortex-M3 Devices Generic User Guide (ARM DUI 0552A) — разд. 3.1, табл. 3-1 — сводка команд Cortex-M3: команд SMLAD, QADD, SADD16 нет; разд. 3.7: команды насыщения — только SSAT и USAT
Нашли ошибку?
Смотрите также
- Арифметика с насыщениемОграничение результата границей диапазона вместо переполнения
- Формат QQm.n: дробные числа в целых, Q15 и Q31
- FPU (блок плавающей точки)Аппаратные операции с float в Cortex-M4F: регистры, CPACR, ленивое сохранение
- CMSISСтандарт Arm: заголовки ядра Cortex-M, драйверы, RTOS и описание устройств
- Система команд Thumb-2Команды по группам, Operand2, флаги и условия, IT, переходы, DSP и FPU, M0