Индексирование в массив с SSE

Предположим, что у меня есть массив:

uint8_t arr[256];

и элемент

__m128i x

содержит 16 байт,

x_1, x_2, ... x_16

Я хотел бы эффективно заполнить новый элемент __m128i

__m128i y

со значениями из arr в зависимости от значений в x, таких, что:

y_1  = arr[x_1]
y_2  = arr[x_2]
   .
   .
   .
y_16 = arr[x_16]

Команда для достижения этой цели по существу будет загружать регистр из несмежного набора мест памяти. У меня есть мучительно смутная память о том, что я видел документацию о такой команде, но не могу ее найти сейчас. Он существует? Заранее благодарим за помощь.

Ответ 1

Этот вид возможностей в архитектурах SIMD известен как разгрузка/сборка загрузки/хранения. К сожалению, SSE этого не имеет. Будущие архитектуры SIMD от Intel могут иметь это - злополучный процессор Larrabee был одним из примеров. Пока же вам просто нужно сконструировать свои структуры данных таким образом, чтобы такая функциональность не нужна.

Обратите внимание, что вы можете добиться эквивалентного эффекта, используя, например, _mm_set_epi8:

y = _mm_set_epi8(arr[x_16], arr[x_15], arr[x_14], ..., arr[x_1]);

хотя, конечно, это просто сгенерирует кучу скалярного кода для загрузки вашего вектора y. Это нормально, если вы выполняете такую ​​операцию за пределами критически важных циклов, например. как часть инициализации до цикла, но внутри цикла он, вероятно, будет убийцей производительности.