Как преобразовать 32-разрядные в 16-разрядные целые числа без знака в AVX2? - PullRequest
1 голос
/ 07 марта 2019

Я использую _mm256_cvtps_epi32() для преобразования из 8 float с в 8x32-битные целые числа.Но цель состоит в том, чтобы получить 16-разрядные целые числа без знака.У меня есть 2 вектора a0 и a1, каждый типа __m256i.Какой самый быстрый способ упаковать их так, чтобы 16-битные эквиваленты a0 попадали в младшие 128 битов результата, а эквиваленты a1 попадали в старшие 128 бит?

Вот что яу нас так далеко, где p0 и p1 - это два __m256 вектора по 8 float с каждый:

const __m256i vShuffle = _mm256_setr_epi8(
  0, 1, 4, 5, 8, 9, 12, 13, -1, -1, -1, -1, -1, -1, -1, -1,
  -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 4, 5, 8, 9, 12, 13);
const __m256i a0 = _mm256_cvtps_epi32(p0);
const __m256i a1 = _mm256_cvtps_epi32(p1);
const __m256i b0 = _mm256_shuffle_epi8(a0, vShuffle);
const __m256i b1 = _mm256_shuffle_epi8(a1, vShuffle);
const __m128i c0 = _mm_or_si128(_mm256_extracti128_si256(b0, 0), _mm256_extracti128_si256(b0, 1));
const __m128i c1 = _mm_or_si128(_mm256_extracti128_si256(b1, 0), _mm256_extracti128_si256(b1, 1));
return _mm256_setr_m128i(c0, c1);

1 Ответ

2 голосов
/ 07 марта 2019

Я не тестировал этот код, но он должен помочь вам:

__m256i tmp1 = _mm256_cvtps_epi32(p0);
__m256i tmp2 = _mm256_cvtps_epi32(p1);
tmp1 = _mm256_packus_epi32(tmp1, tmp2);
tmp1 = _mm256_permute4x64_epi64(tmp1, 0xD8);
// _mm256_store_si256 this
...