_mm256_cvtepi64_epi8
- это AVX512. (В частности, AVX512VL; 512-битная версия AVX512F). Вы отметили это, но ваш (оригинальный) заголовок только сказал AVX.
В любом случае, ваши варианты включают в себя выполнение насыщенного сложения в первую очередь с _mm256_adds_epi8
, так что вы можете иметь в 8 раз больше элементов на вектор.
(И, как обсуждалось в комментариях, для умножения 8x8 => 8-битного насыщения, вы можете просто захотеть, чтобы распаковка на линии переместилась на _mm256_mullo_epi16
, и упаковать пары результатов обратно в линию _mm256_packs_epi16
(vpacksswb
). Несмотря на то, что распаковка в пределах дорожки с расширением знака неудобна, поэтому вы можете рассмотреть vpmovsx
. В любом случае, вам определенно не нужно расширять более 16-битных элементов; int16_t
может содержать полное произведение двух int8_t
без переполнения.)
Или, чтобы сделать это так, как вы просили, AVX512 имеет подписанные и неподписанные версии насыщенных инструкций преобразования с понижением, наряду с найденной версией усечения. VPMOVQB
, VPMOVSQB
и VPMOVUSQB
все задокументированы вместе.
__m128i _mm256_cvtsepi64_epi8(__m256i a);
делает насыщение со знаком. Он доступен в версии с источником __m512i
и в версии, которая хранится непосредственно в памяти (опционально как хранилище в маске).
(версия магазина не более эффективна на основных процессорах, но она позволяла KNL / KNM (в котором отсутствует AVX512BW) для узких хранилищ с байтовой маской.)
Не расширяйте ваши данные до 64-битных элементов, если в этом нет необходимости. Это 1/8-ая часть работы на вектор по сравнению с 8-битными элементами, и умножение 32x32 => 32-битных и 64x64 => 64-битных SIMD требует 2 моп на инструкцию на Intel, начиная с Haswell.
Другой вариант - упаковать 2 вектора -> 1 вектор той же ширины, что и 2 входа, но они работают только с инструкциями по пакетированию внутри линии. например, _mm256_packs_epi16
, как указано выше. Они доступны только для крыс размером 10: 1 ios, а не от 64 или 32 до 8 за один шаг. (Так что это еще одна причина избегать слишком большого расширения).
Но если вы посмотрите на общее количество перемешиваний, чтобы получить N байтов выходных данных, оно будет немного впереди. например, для 4 входных векторов вам нужно 2 + 1 тасования вместо 4, чтобы сузить от 32 до 8 бит. (И, возможно, 4-й случайный случай, если вам нужно исправить внутреннюю линию, если вы не смогли передать им инструкции с чередованием данных нечетным / четным в 128-битных каналах). Вы должны взглянуть на общую картину того, сколько перемешиваний (или, возможно, других инструкций, таких как AND или AVX512 байтовое маскирование) требуется для распаковки и перепаковки.
2: 1 имеет преимущество ведя к более широким магазинам, если вы даже сохраняете результаты. Если нет, то это еще большее преимущество по сравнению с новыми инструкциями AVX512 1-> 1, где вам понадобятся тасования, чтобы объединить их в 256-битный вектор.