Intel недавно раскрыла спецификацию AVX10 как средства консолидации подавляющего большинства расширений AVX-512 в единую спецификацию. Целью этого было решение нескольких проблем, в частности, поразительного количества конфигураций, целевых платформ и спагетти из реализаций AVX-512 с несогласованной поддержкой команд. Следует помнить о том, что в первую очередь она используется как средство для объединения всех любимых преимуществ AVX-512 в более мелкие реализации, целевые платформы для которых — это потребительские машины, micro-edge и встроенные системы, у которых нет или не будет тридцати двух 512-битных регистров, необходимых для AVX-512.  После публикации спецификации я публично выразил свой энтузиазм, сделав доклад для сообществ разработчиков Easy Build/HPC с названием «AVX10 for HPC: a reasonable solution to the 7 levels of AVX-512 folly». Статья, которую вы читаете, изначально должна была стать частью доклада, но я решил написать её, чтобы ссылаться в дальнейшем (а ещё потому, что я уже с трудом могу урезать доклад до 90 минут, не говоря уже о предоставленных мне 60 минутах). Для начала разберёмся с обозначением AVX10.N/M: AVX10 — это новый «фундаментальный» векторный/SIMD набор команд для x86_64. .N обозначает версию AVX10 как модификатор версии, что позволяет вносить инкрементные дополнения. Важно заметить, что если вы поддерживаете AVX10.N+3, то должны также поддерживать AVX10.N, N+1 и N+2. Иными словами, пользователям гарантированы надмножества предыдущих наборов команд. Что значит /M? Это отсылка к размеру реализации векторных регистров конкретной версии AVX10.N. В частности, они могут быть 512-битными, 256-битными, или (тема этой статьи) 128-битными. 128-битные регистры, или регистры XMM, были введены в 1999 году в рамках SSE(1) для 32-битных Pentium 3. 256-битные регистры были введены с появлением AVX1 и впервые реализованы в 2011 году в микроархитектуре Sandy Bridge. 512-битные регистры появились в AVX-512 и были реализованы примерно в 2016 году в Xeon Phi, но не были широко доступны до 2017 года, когда выпустили Skylake-X. Чтобы получить представление о том, как все они выглядят, взгляните на сравнение команды сложения упакованных значения одинарной точности с плавающей запятой (add packed single-precision floating-point values, ADDPS), взятое из визуализатора SIMD-команд на сайте officedaytime.com. Поговорив со своими любимыми сотрудниками Intel, я узнал, что не было «конкретных» причин выбора названия AVX10 в качестве потомка AVX512, за исключением маркетинговых. У меня есть альтернативная теория: Та спецификация AVX-512, которая известна нам сегодня, начиналась как гораздо меньшая архитектура набора команд со схемой кодирования VEX, внутри компании и в ранних маркетинговых материалах известная как AVX3. AVX3 была «довольно» скучной, потому что лишь расширяла регистры, оставалась VEX и предоставляла более универсальное fused multiply add, схожее с тем, что AMD пыталась реализовать при помощи команд FMA4. Учитывая эту информацию, можно обозначить расширения AVX512f как AVX3, а если затем исключить расширения только для Xeon Phi, то получится, что у AVX512 есть примерно 6 групп расширений, которые вполне можно назвать отдельными поколениями. Примерно их можно разбить так: AVX3 F, CD, ER, PF AVX4 VL, DQ, BW AVX5 IFMA, VBMI AVX6 BF16 AVX7 VPOPCNTDQ VNNI, VBMI2, BITALG AVX8 VP2INTERSECT – больше не поддерживается AVX9 FP16 AVX10 — новая «большая» спецификация Следует ожидать, что на серверах и HPC все реализации будут соответствовать спецификации AVX10.N/512. Иными словами, следует ожидать, что реализации будут использовать AVX10.N с 512-битными векторами. Это гарантирует полную поддержку любого уже имеющегося кода AVX-512 и продолжение традиции обратной совместимости для x86_64. На потребительских платформах наличие огромного регистрового файла с 32 регистрами, каждый из которых имеет размер 512 битов, можно считать проблематичным и нежизнеспособным решением. Однако, как видно на примерах Zen 4, Alder Lake, Tiger Lake и других архитектур, это вполне реализуемо. Проблема в том, что в мелких «эффективных» ядрах, в частности, в недавних микроархитектурах Intel Gracemont (в Alder Lake и Raptor Lake) и Crestmont (в новых Meteor Lake и Sierra Forest) предпочитают реализовывать только 128-битные физические АЛУ, обеспечивая поддержку AVX2 при помощи так называемой «двойной накачки» (более урезанная версия конвейерной обработки регистров эпохи векторных процессоров). Благодаря этому возможно реализовать 16 x 256-битных регистров AVX2, но при этом требуется реализовать только 128-битные блоки работы с плавающей запятой и целыми числами. Но за это приходится расплачиваться: хотя можно сэкономить на размере кристаллов и мощности, при некоторых нагрузках может наблюдаться серьёзная регрессия производительности. Зная об этом, умные ребята из Intel, проектирующие спецификацию AVX10, затребовали, чтобы все реализации имели 32 регистра, но эти регистры должны иметь ширину, равную /M. Это значит, что AVX10/256 будет иметь те же возможности команд, что и AVX10/512, но требует, чтобы 32 регистра имели ширину всего 256 битов. По большей части, любой код, написанный для старых расширений AVX-512, ограниченных 256-битными регистрами, должен* нормально работать, достаточно лишь его перекомпилировать. Подобный код возникал в результате знаменитой угрозы «AVX-512 down-clocking», которая «наказывает» за использование 512-битной части AVX-512. Хорошая сторона заключается в том, что большая часть кода уже спроектирована под «упрощённую» 256-битную версию AVX-512, и его не будет легко подвергнуть миграции, когда настанет время. *Ситуация чуть сложнее, чем описано выше, но код можно заставить работать за несколько часов или дней. При чтении спецификации AVX10 (технический документ Intel по AVX10, полная спецификация AVX10) внимание привлекают несколько пунктов. А именно, в техническом документе многократно используется слово «converged». Какие фичи являются converging? Это все уникальные фичи AVX-512 которые не являются просто «большими регистрами». Например, такие вещи, как числа с плавающей запятой с половинной точностью IEEE-754 поддерживаются как часть AVX10. А как насчёт brain floating point 16 (BF16), урезанной версии FP32, используемой в модном сегодня ИИ? Они поддерживаются как часть AVX10. А как насчёт любимых всеми программистами на ассемблере AVX-512 команд динамически перепрограммируемых операторов троичной логики? Они поддерживаются как часть AVX10. По сути, все крутые штуки, которые нужны программистам ассемблера и компиляторов для ускорения приложений благодаря более умной архитектуре алгоритмов, включены как часть AVX10. Ещё одно важное требование AVX10 заключается в том, что все реализации должны полностью реализовывать AVX2 и его 16 x 256-битных регистров. В свою очередь, вы гарантированно получаете поддержку кода AVX2 на своём процессоре. Если говорить математически, можно воспринимать это как то, что AVX10 имеет в своём множестве полное множество AVX2. В свою очередь, AVX2 требует полного множества AVX1. С моей точки зрения, существуют три «базовых» проблемы: Любые реализации в той или иной степени будут «прокляты». Это вызывает проблемы у ПО, разработчики которого пытаются реализовать спецификацию.   По сути, это утраивает трудозатраты разработки для каждого поколения.  Любая реализация AVX2 должна иметь 16 x 256-битных регистров. AVX10 требует 32 векторных регистров вне зависимости от размера вектора. В случае AVX10.N/128, это будет 32 x 128-битных регистров. С точки зрения (предполагаемой) инженера/архитектора, занимающегося проектированием ядра, дерево принятия решений для AVX10/128 будет выглядеть так: Любая реализация, которая обеспечивает поддержку только до AVX10/128, должна поддерживать 16 256-битных регистров YMM, они же YMM0-15, и вторичный набор 128-битных регистров XMM в интервале XMM16-31. У архитектора возникает ещё несколько вариантов выбора. Выбрать ли два разных класса векторных регистров SIMD разного размера? Можно ли альтернативно использовать верхнюю половину битов 128-255 ymm0-15 в качестве битов 0-127 xmm16-31? Можно ли расширить xmm16-31 до 256 битов? Третий вариант наиболее вероятен для «чистой» реализации. Но потом вас осеняет: постойте-ка! Я создал тот регистровый файл, который нужен мне для AVX10/256! Если бы я реализовал чуть больше логики управления, то у меня была полнофункциональная реализация AVX10/256 и я бы мог сэкономить свои 128-битные FPU и АЛУ! А знаете, мы ведь делали так раньше! А именно для Zen 4 и Zen4c AMD реализовала AVX512 на основе 256-битных FPU. Когда в Zen 1 приняли AVX2, там также выполняли «двойную накачку» 128-битного целочисленного блока. До этого в микроархитектуре Bulldozer был реализован AVX1 с 128-битными FPU! И это относится не только к AMD! Сегодня Intel делает тоже самое с 128-битными FPU и целочисленными АЛУ в Gracemont. Поэтому вы делаете шаг назад и осознаёте, что изначально реализовали «двойную накачку», потому что вам нужна поддержка 16 x 256-битных регистров для AVX1 и 2! В частности, AVX требуется логика для адресации, маскирования, загрузки и сохранения и верхней, и нижней части регистра. Следующий шаг относительно прост: устранение проблем оптимизации реализации ПО в современных реализациях ISA. Одна из гарантий AVX10 заключается в том, что любая реализация будет поддерживать все меньшие валидные реализации. Иными словами, хотя платформы AVX10/512 поддерживают AVX10/256, платформы AVX10/256 не поддерживают AVX10/512. Следовательно, платформы  AVX10/256-512 поддерживают AVX10/128. Но вот в чём проблема: с точки зрения нацеленности ПО, когда AVX10 станет достаточно распространённым, чтобы стать целевой платформой x86_64 по умолчанию (а это случится примерно в течение десятка лет), AVX10/128, как самый совместимый вариант, станет в конечном итоге даунгрейдом по сравнению с AVX2 для SIMD-программ. Если AVX10/128 валиден и проложит себе дорогу на рынок, то он станет де-факто минимальной целевой платформой для AVX10, потому что поддерживает все сетевые и потребительские опции. Хотя справедливо, что лучшее в AVX-512 — не 512 битов, одновременно справедливо и то, что даунгрейд до 128-битных регистров в качестве стандартной целевой платформы пойдёт во вред генерации SIMD-кода: напоминаю, что мы поднялись выше 128-битных регистров на потребительских платформах более десятка лет назад. Генерация кода ушла дальше. Действительно ли спустя десять лет мы захотим быть привязанными к 128-битным регистрам с улучшенными командами?   Мой последний аргумент заключается в том, что с точки зрения ПО AVX10 только с 256-битными и 512-битными опциями, по сути, удваивает бремя для каждого поколения. Это уже произошло с потребительскими Golden Cove и корпоративными Golden Cove. А именно, первые поддерживают архитектуры только до AVX2, а в последних реализован весь AVX512 (вплоть до совместимости с AVX10.1/512). «Одна и та же» микроархитектура (uArch) может иметь разные конфигурации памяти, различное количество блоков Fused Multiply Add (FMA), разные количества блоков векторного сложения и так далее. В примере с Golden Cove мы имеем: потребительский AVX2 с DDR4 и DDR5, AVX-512 для рабочих станций с DDR5, серверный AVX-512 с DDR5, серверный AVX-512 только с HBM и серверный AVX-512 с основной памятью DDR5 и кэшем HBM. В HPC привыкли к использованию множественных версий для различных подплатформ ISA, но разработчики потребительского ПО избегают этого любой ценой. Вам повезёт, если мейнтейнеры потребительского ПО включат поддержку чего-то выше SSE2, не говоря уже о какой-нибудь разновидности AVX. И я их не виню. С точки зрения поддержки неразумно просить каждый менеджер пакетов компилировать разные версии проектов под разные версии ISA, подстраиваться под разные платформы и каким-то образом умудряться всегда их собирать. И теперь вы хотите добавить всё это поверх уже существующей нагрузки на управление пакетами? Не думаю, что это хорошая идея. В сфере HPC можно рассчитывать, что большинство пользователей перекомпилирует ПО под свои кластеры, но на потребительских платформах такого не случится. Да даже Arch Linux не реализует это в экспериментальном режиме! Моя просьба к Intel проста. На странице 1-2 документа Intel 355989-001US, rev 1.0, сейчас написано:  Для Intel AVX10/256 поддерживаются 32-битные длины регистров маски операндов. Для Intel AVX10/512 поддерживается 64-битная маска операндов. Пока нет планов на поддержку реализации Intel AVX10/128.  Я прошу, чтобы текст поменяли на такой: Для Intel AVX10/256 поддерживаются 32-битные длины регистров маски операндов. Для Intel AVX10/512 поддерживается 64-битная маска операндов. Поддержка для реализации только Intel AVX10/128 не предоставляется в этой спецификации. Все реализации AVX10/256 и AVX10/512 должны обеспечивать возможность операций со скалярными и 128-битными векторными регистрами. Такая конкретная формулировка нужна для гарантий того, что если Intel когда-нибудь захочет исследовать архитектуру на основе AVX10, предназначенную для многоядерного продукта, концептуально подобного Xeon Phi, то у компании была бы такая возможность. Благодаря этому компиляторы, разработчики библиотек и другие поставщики ПО не будут находиться во подвешенном состоянии. Это позволяет не оставлять возможности для того, что допускается по спецификации, но не попадёт на рынок. В конечном итоге, изменения всё равно позволят им создать продукт, но проектирующие продукт могут взять на себя ношу его поддержки, оставив в покое нас, обычных разработчиков. Продукт, вероятно, будет «простым» ядром Atom, реализующим скалярные версии AVX10, и у каждого ядра будет собственный блок AMX. Но пусть такими рассуждениями о продуктах занимаются другие части нашей отрасли. Так что я смиренно прошу: Intel, пожалуйста, сделай AVX10/128 недопустимой реализацией в текущей спецификации.   Переводчик-фрилансер