Преобразовать массив из восьми байтов в восемь целых
Я работаю с 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;
}