Можно ли использовать AVX-512 для вычисления умножения двух 256-битных целых чисел на 64-битном компьютере на C++? Используете ли ассемблер или нет

Что касается арифметики произвольной точности: можно ли использовать AVX-512 для вычисления умножения двух 256-битных целых чисел на 64-битном компьютере на C++? Существует ли встроенный 512-битный тип данных Integer для результата в компиляторе C++, который делает это возможным?

Если это невозможно, можно ли это сделать на языке ассемблера? Если да, то можно ли вызвать эту процедуру на языке ассемблера из программы на C++? Может ли 512-битный результат процедуры языка ассемблера использоваться 64-битными целочисленными типами данных без использования строки?

Вы можете использовать Intel Intrinsics для доступа ко всем инструкциям AVX512 из C/C++. Однако AVX не имеет расширенного умножения. Лучшее, что вы можете получить, — это векторизованное знаковое 64-битное умножение, которое возвращает младшие 64 бита результата для 8 независимых умножений (_mm512_mullo_epi64) или 8 x 32-битных умножений с полными 64-битными результатами (_mm512_mul_epi32 для знаковых, _mm512_mul_epu32 для беззнаковых).

Homer512 10.06.2024 08:19

512 означает максимальный объем данных, которые могут быть обработаны одновременно, но каждый элемент в 512-битном блоке по-прежнему имеет длину не более 64 бит intel.com/content/www/us/en/docs/intrinsics-guide/index. html‌​#

Alan Birtles 10.06.2024 08:19

Технически да, но не с одной инструкцией с простым форматом хранения. См. Могут ли подпрограммы с длинными целыми числами выиграть от SSE? - ускорение возможно при использовании форматов хранения, которые оставляют некоторые биты неиспользованными в каждой 64-битной конечности, что позволяет AVX-512IFMA или bithacks использовать часть мантиссы FMA (как это делает Prime95 или y-Cruncher).

Peter Cordes 10.06.2024 08:22
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
3
137
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Да и нет.

Нет, в AVX-512 нет инструкции по умножению двух 256-битных операндов для получения 512-битного результата. Максимальные операнды, которые вы можете умножить, имеют длину 64 бита каждый, чтобы получить 128-битный результат.

Итак, чтобы умножить 256-битные операнды, вы делаете что-то вроде умножения в начальной школе. За исключением того, что вы хотите рассматривать 256-битное число как четырехзначное число по основанию 264. Итак, у вас есть что-то вроде:

          D  C  B  A
          H  G  F  E
--------------------
         ED EC EB EA
      FD FC FB FA 0
   GD GC GB GA 0  0
HD HC HB HA 0  0  0
--------------------

[где HD означает H*D, GB означает G*B и так далее.]

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

Разница в том, что вместо того, чтобы каждая цифра была цифрой от 0 до 9, в этом случае каждая цифра идет от 0 до 264-1.

Но да, поскольку вам приходится выполнять одинаковые операции с каждым из нескольких операндов, вполне разумно выполнять их параллельно, используя векторные инструкции. Но это просто параллельное выполнение нескольких 64-битных умножений, а не работа с каким-либо отдельным операндом, размер которого превышает 64 бита1.

Если вы работаете с действительно большими числами (например, миллионами цифр или более), есть более эффективные методы умножения, такие как умножение Карацубы и умножение Шёнхаге-Штрассена, но 512 бит почти наверняка слишком малы для того, чтобы получить заметную выгоду от таких вещей.


  1. Однако я должен добавить, что, хотя идея векторного выполнения верна, она может потребовать много работы с небольшой выгодой или вообще без нее, поэтому, если вы не выполняете много таких операций в узком цикле, она открыта для большого количества операций. вопрос, будет ли это того стоить.

Хороший ответ. Но… поправьте меня, если я ошибаюсь: для этого вам понадобится 64-битное умножение, которое генерирует 128-битные результаты, верно? Возвращаясь к примеру с начальной школой, вам нужно выполнить однозначное умножение, которое может привести к двузначному результату (9x9 = 81 и т. д.). Поскольку в AVX этого нет, нам нужно выполнить векторизованное 32-битное умножение, которое даст 64-битный результат. И когда мы делаем сложения, нам приходится беспокоиться о битах переноса.

Homer512 10.06.2024 09:01

@Homer512: Homer512: Да, это правда. Если вы имеете дело с чем-то, что не может генерировать результат двойного размера, вы обычно начинаете с разбиения его на 32-битные фрагменты, чтобы отдельные результаты помещались в 64-битные регистры (или, в более общем смысле, в отдельные регистры). размер регистра, чтобы каждый результат помещался в регистр).

Jerry Coffin 10.06.2024 09:45

Вам придется много перетасовывать и складывать с переносом, что, вероятно, не оправдает затраченных усилий, если вы создадите только один продукт размером 256x256. Если у вас действительно большие продукты и у вас есть AVX512IFMA52, возможно, стоит рассмотреть возможность разделения числа на 52-битные части (vpmadd52luq и vpmadd52huq имеют лучшую пропускную способность, а окончательное сложение переноса можно выполнить в самом конце).

chtz 10.06.2024 10:43

Другие вопросы по теме