2013-10-24 56 views
5

假設我有上證所SSE4.1,而不是AVX(2),什麼是加載一個包裝的內存佈局是這樣的(所有32位整數),最快的方法:在沒有AVX(2)的情況下進行SIMD收集的最快方法是什麼?

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個向量,因此a0a1相距16個* 4字節的內存。

回答

9

你所需要的就是4個負載後跟一個4x4的轉置:

#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個。 –

相關問題