Используя встроенные функции AVX / AVX2, я могу собрать наборы из 8 значений, 1,2- или 4-байтовых целых чисел или 4-байтовых чисел с плавающей запятой, используя:
_mm256_i32gather_epi32 ()
_mm256_i32gather_ps ()
Но в настоящее время у меня есть случай, когда я загружаю данные, которые были сгенерированы на графическом процессоре nvidia и сохранены как значения FP16. Как я могу сделать векторизованную загрузку этих значений?
До сих пор я нашел _mm256_cvtph_ps () intrinsi c.
Однако, ввод для этого intrinsi c - это значение __ m128i , а не значение __ m256i .
Глядя на Intel Intrinsics Guide, я не вижу операций сбора, которые хранят 8 значений в регистр _mm128i?
Как я могу собрать значения FP16 в 8 дорожек регистра __m256? Можно ли векторно загрузить их как 2-байтовые шорты в __m256i, а затем как-то уменьшить это до значения __m128i, которое будет передано в преобразование intrinsi c? Если это так, я не нашел встроенных функций для этого.
ОБНОВЛЕНИЕ
Я пробовал приведение, как было предложено @ peter-cordes, но получаю поддельные результаты от который. Кроме того, я не понимаю, как это может работать?
Мои 2-байтовые значения int хранятся в __m256i как:
0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX 0000XXXX
так как я могу просто приведение к __m128i, где он должен быть плотно упакован как
XXXX XXXX XXXX XXXX XXXX XXXX XXXX XXXX
Будет ли это делать?
Мой текущий код:
__fp16* fielddensity = ...
__m256i indices = ...
__m256i msk = _mm256_set1_epi32(0xffff);
__m256i d = _mm256_and_si256(_mm256_i32gather_epi32(fielddensity,indices,2), msk);
__m256 v = _mm256_cvtph_ps(_mm256_castsi256_si128(d));
Но результат не похоже на 8 правильно сформированных значений. Я думаю, что каждый второй сейчас для меня фальшивка?