Как стать автором
Обновить
Selectel
IT-инфраструктура для бизнеса

Процессоры ARM: смешиваем NEON с SVE — и забава, и польза

Уровень сложностиСредний
Время на прочтение3 мин
Количество просмотров1.2K
Автор оригинала: Daniel Lemire

Большинство мобильных устройств используют 64‑битные ARM‑процессоры. Однако они все заметнее и на серверах. Их число неуклонно растет, и все больше компаний, включая таких гигантов, как Amazon и Microsoft, также переходят на 64‑битные ARM.

У этих процессоров есть специальные инструкции — ARM NEON. Они обеспечивают параллелизм, известный как SIMD — Single Instruction, Multiple Data, то есть «Инструкция одна, данных множество». Например, можно сравнить шестнадцать одних значений с шестнадцатью других с помощью всего одной такой инструкции.

Некоторые из самых последних процессоров ARM также поддерживают еще более продвинутый набор команд — SVE, Scalable Vector Extension, или «Масштабируемое векторное расширение». Прогресс не останавливается — и вот уже появились спецификации SVE 2 и SVE 2.1.

Немного теории


Регистры NEON имеют четкое ограничение — размерность 128 бит. Регистры же SVE кратны 128 битам. Да, на практике они тоже чаще всего имеют размер 128 бит, как и NEON, но все же попадаются и исключения. Например, Amazon Graviton 3 основан на ядре ARM Neoverse V1, которое поддерживает SVE с длиной вектора 256 бит (32 байта). Что касается Graviton 4, он основан на ядре ARM Neoverse V2, которое поддерживает более развитый SVE2, правда с длиной вектора тоже 16 байт — как и «младший» NEON.

Кому по силам работать на таком low level, тому приходится выбирать между NEON и SVE.

Как отметил Ashton Six в комментарии к моей недавней статье, эти инструкции (NEON и SVE) можно смешивать и сочетать — в документации гарантируется, что первые 128 бит регистров SVE являются и регистрами NEON. Эштон продемонстрировал это на практическом примере кода на ассемблере.

Если компилятор C/C++ довольно свеж (хотя бы, GCC 14), можно легко переключаться между NEON и SVE. Если раздобыть заголовочный файл arm_neon_sve_bridge.h, достаточно описать две функции:
  • svset_neonq: устанавливает содержимое 128‑битного вектора NEON (uint8x16_t, int32x4_t и  другие) в вектор SVE (svuint8_t, svint32_t… — ряд можно продолжить);
  • svget_neonq: извлекает первые 128 бит вектора SVE и возвращает их в виде 128‑битного вектора NEON.

Эти функции «бесплатны»: скорее всего, они компилируются вообще без инструкций.

Проверьте ARM-процессор в своих задачах.
Сервер с 128-ядерным процессором Ampere® Altra® Max M128-30 и 256 ГБ DDR4 уже в Selectel.



Переходим к практике


Позвольте проиллюстрировать на примере. В недавнем посте обсуждалось, что сложновато проверить, есть ли ненулевой байт в регистре NEON. Конкурентоспособное решение выглядит следующим образом:

int veq_non_zero_max(uint8x16_t v) {
    return vmaxvq_u32(vreinterpretq_u32_u8(v)) != 0;
}

По сути, мы вычисляем в регистре максимальное 32‑битное целое, рассматривая его как четыре 32‑битных целых. Такая функция компилируется в три основные инструкции: umaxv, fmov и cmp.

Рассмотрим альтернативу SVE. Происходит следующее:
  • входные данные преобразуются в вектор SVE;
  • создается маска для всех 16 позиций;
  • каждый элемент сравнивается с нулем, чтобы сгенерировать предикат ненулевых позиций;
  • проверяется, есть ли какие‑либо ненулевые элементы;
  • наконец, возвращается 1, если да, и 0, если нет.

По сути, выполняется эффективная векторизованная проверка: «есть ли хоть один ненулевой»?

int sve_non_zero_max(uint8x16_t nvec) {
  svuint8_t vec;
  vec = svset_neonq_u8(vec, nvec);
  svbool_t mask = svwhilelt_b8(0, 16);
  svbool_t cmp = svcmpne_n_u8(mask, vec, 0);
  return svptest_any(mask, cmp);
}

Если не считать инициализации маски, функция состоит из двух инструкций: cmpne и cset. В некоторых ядрах ARM они могут быть объединены в одну. Несмотря на то, что код, смешивающий NEON и SVE, на первый взгляд выглядит сложнее, на деле он получается эффективнее!

Если процессор, с которым вы работаете поддерживает SVE (SVE 2, SVE 2.1), и уже есть код для NEON, то можете попробовать добавить в него немного SVE.
Теги:
Хабы:
+8
Комментарии3

Публикации

Информация

Сайт
slc.tl
Дата регистрации
Дата основания
Численность
1 001–5 000 человек
Местоположение
Россия
Представитель
Влад Ефименко