2013-10-24 9 views
5

Предполагая, что у меня есть SSE к SSE4.1, но не AVX (2), что это самый быстрый способ загрузить упакованный макет памяти, как это (все 32-разрядные целые):Каков самый быстрый способ сделать SIMD-сбор без AVX (2)?

a0 b0 c0 d0 a1 b1 c1 d1 a2 b2 c2 d2 a3 b3 c3 d3 

В четырех векторов a, b, c, d ?

a: {a0, a1, a2, a3} 
b: {b0, b1, b2, b3} 
c: {c0, c1, c2, c3} 
d: {d0, d1, d2, d3} 

Я не уверен, является ли это отношение или нет, но в моем фактическом применении у меня есть 16 векторов и, как таковые a0 и a1 16 * 4 байта друг от друга в памяти.

ответ

9

Что вам нужно здесь 4 нагрузки с последующим 4х4 транспонированной:

#include "emmintrin.h"      // SSE2 

v0 = _mm_load_si128((__m128i *)&a[0]);  // v0 = a0 b0 c0 d0 
v1 = _mm_load_si128((__m128i *)&a[16]);  // v1 = a1 b1 c1 d1 
v2 = _mm_load_si128((__m128i *)&a[32]);  // v2 = a2 b2 c2 d2 
v3 = _mm_load_si128((__m128i *)&a[48]);  // v3 = a3 b3 c3 d3 

// 4x4 transpose 

w0 = _mm_unpacklo_epi32(v0, v1);    // w0 = a0 a1 b0 b1 
w1 = _mm_unpackhi_epi32(v0, v1);    // w1 = c0 c1 d0 d1 
w2 = _mm_unpacklo_epi32(v2, v3);    // w2 = a2 a3 b2 b3 
w3 = _mm_unpackhi_epi32(v2, v3);    // w3 = c2 c3 d2 d3 
v0 = _mm_unpacklo_epi64(w0, w2);    // v0 = a0 a1 a2 a3 
v1 = _mm_unpackhi_epi64(w0, w2);    // v1 = b0 b1 b2 b3 
v2 = _mm_unpacklo_epi64(w1, w3);    // v2 = c0 c1 c2 c3 
v3 = _mm_unpackhi_epi64(w1, w3);    // v3 = d0 d1 d2 d3 

Примечание: это, вероятно, более эффективно, чем использование AVX2 собрали нагрузки, так как они создают цикл чтения для каждого элемента, что делает их действительно только полезно, когда шаблон доступа неизвестен или с ним трудно работать.

+0

Возможно, вы пропустили предложение по моему вопросу о наличии 16 векторов вместо 4. Должен ли я использовать как 4 транспозиции? – orlp

+1

Действительно - не зная, что вы планируете делать со всеми этими векторами, сложно дать полное решение, но да, вы можете просто повторить вышеуказанные шаги для остальных 12 векторов в группах по 4. –

 Смежные вопросы

  • Нет связанных вопросов^_^