Преобразовать массив из восьми байтов в восемь целых - PullRequest
0 голосов
/ 24 ноября 2018

Я работаю с Xeon Phi Knights Landing.Мне нужно сделать операцию сбора из массива пар.Список индексов происходит из массива символов.Операции сбора могут быть либо _mm512_i32gather_pd, либо _mm512_i64gather_pd.Насколько я понимаю, мне нужно либо преобразовать восемь символов в восемь 32-разрядных чисел, либо восемь символов в 64-разрядные целые числа.Я выбрал первый выбор для _mm512_i32gather_pd.

. Я создал две функции get_index и get_index2 для преобразования восьми символов в __m256i.Сборка для get_index проще, чем для get_index2, см. https://godbolt.org/z/lhg9fX. Однако, в моем коде get_index2 значительно быстрее. Почему это так? Я использую ICC 18. Может быть, есть лучшее решение, чем любая из этих двух функций?

#include <x86intrin.h>
#include <inttypes.h>

__m256i get_index(char *index) {                                                                                                                                      
  int64_t x = *(int64_t *)&index[0];                                                                                                                                             
  const __m256i t3 = _mm256_setr_epi8(
    0,0x80,0x80,0x80,
    1,0x80,0x80,0x80,
    2,0x80,0x80,0x80,
    3,0x80,0x80,0x80,
    4,0x80,0x80,0x80,
    5,0x80,0x80,0x80,
    6,0x80,0x80,0x80,
    7,0x80,0x80,0x80);                                                                                                                                                     

  __m256i t2 = _mm256_set1_epi64x(x);                                                                                                                                            
  __m256i t4 = _mm256_shuffle_epi8(t2, t3);                                                                                                                                      
  return t4;                                                                                                                                                                     
}                

__m256i get_index2(char *index) {
  const __m256i t3 = _mm256_setr_epi8(
    0,0x80,0x80,0x80,
    1,0x80,0x80,0x80,
    2,0x80,0x80,0x80,
    3,0x80,0x80,0x80,
    4,0x80,0x80,0x80,
    5,0x80,0x80,0x80,
    6,0x80,0x80,0x80,
    7,0x80,0x80,0x80);
  __m128i t1  = _mm_loadl_epi64((__m128i*)index);
  __m256i t2 = _mm256_inserti128_si256(_mm256_castsi128_si256(t1), t1, 1);
  __m256i t4 = _mm256_shuffle_epi8(t2, t3);
  return t4;
}
...