AVX2, Как эффективно загрузить четыре целых числа в четные индексы 256-битного регистра и копировать в нечетные индексы?

У меня есть выровненный массив целых чисел в памяти, содержащий индексы I0, I1, I2, I3. Моя цель - поместить их в регистр __m256i, содержащий I0, I0 + 1, I1, I1 + 1, I2, I2 + 1, I3, I3 + 1. Сложная часть заключается в том, чтобы поместить их в 256-битный регистр как I0, I0 , I1, I1, I2, I2, I3, I3, после чего я могу просто добавить регистр, содержащий 0, 1, 0, 1, 0, 1, 0, 1.

Я нашел встроенную функцию _mm256_castsi128_si256, которая позволяет мне загрузить 4 целых числа в младшие 128 бит 256-битного регистра, но я изо всех сил пытаюсь найти лучшие встроенные функции для использования оттуда.

Любая помощь будет оценена. У меня есть доступ ко всем версиям SSE, AVX и AVX2, и я хотел бы сделать это, используя только встроенные функции.

Редактировать:

Я думаю, что это работает, но я не настолько эффективен ... в процессе тестирования.

// _mm128_load_si128: Loads 4 integer values into a temporary 128bit register.
// _mm256_broadcastsi128_si256: Copies 4 integer values in the 128 bit register to the low and high 128 bits of the 256 bit register.
__m256i tmpStuff = _mm256_broadcastsi128_si256 ((_mm_load_si128((__m128i*) indicesArray)));

// _mm256_unpacklo_epi32: Interleaves the integer values of source0 and source1.
__m256i indices = _mm256_unpacklo_epi32(tmpStuff, tmpStuff);

__m256i regToAdd = _mm256_set_epi32 (0, 1, 0, 1, 0, 1, 0, 1);
indices = _mm256_add_epi32(indices, regToAdd);

Edit2: приведенный выше код не работает, потому что _mm256_unpacklo_epi32 не ведет себя так, как я думал. Приведенный выше код приведет к I0, I0 + 1, I1, I1 + 1, I0, I0 + 1, I1, I1 + 1.

Edit3: следующий код работает, хотя, опять же, я не уверен, является ли он наиболее эффективным:

__m256i tmpStuff = _mm256_castsi128_si256(_mm_loadu_si128((__m128i*) indicesArray));
__m256i mask = _mm256_set_epi32 (3, 3, 2, 2, 1, 1, 0, 0);
__m256i indices= _mm256_permutevar8x32_epi32(tmpStuff, mask);
__m256i regToAdd = _mm256_set_epi32 (1, 0, 1, 0, 1, 0, 1, 0); // Set in reverse order.
indices= _mm256_add_epi32(indices, regToAdd);

Ответы на вопрос(1)

Ваш ответ на вопрос