簡體   English   中英

使用指針的向量移位

[英]vector shift using pointers

我正在使用SSE3優化代碼。 代碼中有一點迫使我將向量中的所有元素移動一個元素

v[0] = 0   //v is some char* and N = v.size()
for(int i = 1;i<N;i++){
    v[i] = v[i-1];
}

據我所知,SSE不支持向量移位,因此我必須從頭開始編寫這一代碼。

但是后來我有了主意,如果我只是減小指針呢?

v = (v-1); 
v[0] = 0;

這樣,操作將是恆定的,根本不需要任何操作。

我已經測試過了,它適用於我的測試程序。
但是,我不確定此操作是否安全。

這是一個很愚蠢的主意嗎?

SSE確實支持移位,即向量內元素的按位移位以及整個寄存器沿字節邊界的移位。

假設您的向量的類型是uint8_t 16倍,那么您要查找的操作是

psrldq xmm, 1      ;packed shift right logical double quad word

與內在

vec = _mm_srli_si128(vec, 1);   // shift by 1 byte

對於第一個問題:只要v是指向char的指針,則對其進行減量或增量操作是完全安全的。 取消引用可能不行,這取決於您的程序。

關於第二個問題:是的,這看起來很愚蠢。 如果您嘗試使用SSE進行優化,並且使用指向字節的指針來執行某些任務,則您很可能做錯了什么,如果您嘗試將v 16加載到SSE寄存器中,則會引發麻煩-可能是由於未對齊而導致段錯誤或由於強制編譯器使用movdqu而導致性能movdqu

最簡單的答案:使用memmove(v + 1,v,N-1)代替發布的循環。 這可以在任何體面的系統上以與手動編碼程序集一樣快的速度運行,因為它手動編碼程序集,使用movdqu / movdqa / movntdqa和循環展開的適當組合。

更復雜的答案:我認為,從更大的角度來看,實際上不太可能需要轉移數據 您很有可能需要訪問相鄰元素和當前元素,例如,對v [i]和v [i-1]進行某種計算。

如果使用SIMD代碼執行此操作,則標准技術是(例如)將字節0..15裝入xmm0,將16..31字節裝入xmm1,然后將兩個寄存器進行混洗以最后包含元素1..16 xmm2。 然后,您可以使用xmm0(此處對應於矢量化v [i-1])和xmm2(矢量化v [i])進行計算。 從邏輯/算術移位的意義上講,這不是“移位”,而是SIMD通道移位。

示例:在匯編中使用字節

movdqa mem, xmm0 // load bytes 0..15
loop:
// increment mem by 16
movdqa mem, xmm1 // load bytes 16..31
movdqa xmm0, xmm2 // make a copy
movdqa xmm1, xmm3 // make a copy
psrldq xmm2, 1 // ends up with bytes 1..15 and a zero
pslldq xmm3, 15 // ends up with zeros and byte 16
por xmm2, xmm3 // ends up with bytes 1..16
// do something with xmm3 and xmm0 here, they contain bytes 1..16 and 0..15 respectively
// in other words xmm3 is a lane-shifted
movdqa xmm1, xmm0 // use our copy of bytes 16..31 to continue the loop
// goto loop

為什么不這樣做:“如果我只是減少指針... v =(v-1),該怎么辦;”

這將崩潰:

char* v = (char*)malloc(...);
v=(v-1);
v[0] = 0; // or any read or write of v[0]

如果v指向分配的內存塊中間(而不是開頭)的某個位置,則減量可以正常工作,但是必須確保始終如此(例如,分配內存)在將使用此技巧的相同功能中)。

減小指針將首先導致對第0個元素的訪問超出范圍, 並且將使向量不對齊。 向量運算,除了要正確對齊才能有效的數據。 如果數據未對齊,則指令調度程序必須將對內存的讀取拆分為兩次訪存,從而降低性能。

SSE對整個向量提供位移操作,請參見@hirschhornsalz的答案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM