2014-10-10 36 views
2

假設我有8個SSE寄存器,枚舉爲r0,r1,r2,...,r7,並且每個都包含8個16位整數。我想創建一個新的寄存器,其中包含8個寄存器中的第i個元素,從r0開始,到r7。換句話說,我想獲得一個寄存器具有以下內容:從多個寄存器中收集特定元素並存儲到一個寄存器

r0[i],r1[i],r2[i],r3[i],r4[i],r5[i],r6[i],r7[i]

會如何,使用SSE(或AVX)做些什麼呢?

謝謝!

請注意,索引i不是常數,而是在運行時計算的。

+2

你想要做什麼你所描述的將會非常慢你試圖做轉置什麼的? – Mysticial 2014-10-10 05:53:21

+2

你可以用7個PSHUFB指令做到這一點,但如果你加入你想通過這樣來實現的,因爲有可能是一個更好的整體解決方案是什麼一番解釋可能會更好。 – 2014-10-10 06:08:26

+0

感謝您的回覆。很難解釋,但原則上我使用SSE逐列計算矩陣。結果是矩陣的最後一列和最後一行。我已經通過使用8個16位值的矢量向量化該方法,以便逐列地計算矩陣。我已經將矩陣的列長度(clen)填充爲8的倍數,這樣我就可以每列執行8次矢量計算。我總是覆蓋計算,即在內存中我總是隻有前一列的結果。在計算結束時,結果是最後一列(我想要的)。 – Tomas 2014-10-10 11:04:31

回答

1

這似乎是一個有趣的挑戰。如果你需要做到這一點在你的算法,它的時間去思考怎麼回事組織的事情,所以你要做只是這一點,而不是像一個整體的8x8轉保羅的R意見建議。

我想的有點像pshufb爲每個寄存器設置

xmmN[N] = old_xmmN[i]; // with other elements zeroed. 

你必須洗牌口罩的表,並使用table[ (i-N) & 7]爲shufflign xmmN。或者,在零之前/之後重複洗牌蒙版,您可以使用從table[i]開始的8個連續蒙版。 (所以你計算的地址轉換成註冊一次,並使用增加的位移。

然後POR寄存器一起在樹上。(實際上,選擇第一POR操作數和前兩個PSHUFB年代後權安排,所以合併可與洗牌重疊。)

你可能被存儲到內存中,然後重裝獲得更好的吞吐量。(但也許更糟糕的等待時間,因爲店裏轉發延遲,這將導致的)。

rdi = tmp buffer 
switch(i) { 
    case 0: 
     movd [rdi], xmm0 
     movd [rdi+2], xmm1 
     ... 
     movd [rdi+14], xmm8 // note: writes all the way to [rdi+17]. use pextrw to avoid that. 
     break; 
    case 1: 
     pextrw [rdi], xmm0, 1; // SSE4.1 for memory dest pextrw 
     pextrw [rdi+2], xmm1, 1 
     ... 
     break; 
    case 2: 
     same, but with imm8 = 2; 
     break; 
    ... 
} 
movdqa xmm0, [rdi] ;// ~10 cycle store-forwarding stall 
相關問題