![](/img/trans.png)
[英]How do I pass an immediate 4 bit value to the last argument of _mm256_blend_pd
[英]How do the shuffle/permute intrinsics work for 256 bit pd?
我試圖圍繞_mm256_shuffle_pd和_mm256_permute_pd內在函數如何工作。 我似乎無法預測其中一項操作的結果。
首先,對於_mm_shuffle_ps一切都很好。 我得到的結果是我期待的結果。 例如:
float b[4] = { 1.12, 2.22, 3.33, 4.44 };
__m128 a = _mm_load_ps(&b[0]);
a = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 1, 2));
_mm_store_ps(&b[0], a);
// 3.33 2.22 1.12 4.44
所以一切都在這里。 現在我想用__m256d嘗試這個,這是我目前在我的代碼中使用的。 從我發現的_mm256_shuffle_ps / pd內在函數的工作方式不同。
我的理解是控制掩碼應用了兩次。 第一次在128位的前半部分,第二次在最后的128位。 前兩對控制位用於從第一矢量中選擇(並將值存儲在第一和第二字以及結果矢量的第五和第六字中),而最高位對選擇第二矢量。 例如:
float b[8] = { 1.12, 2.22, 3.33, 4.44, 5.55, 6.66, 7.77, 8.88 };
__m256 a = _mm256_load_ps(&b[0]);
a = _mm256_shuffle_ps(a, a, 0b00000111);
_mm256_store_ps(&b[0], a);
// 4.44 2.22 1.12 1.12 8.88 6.66 5.55 5.55
這里我期望(我實際得到的)結果是{ 4.44, 2.22, 1.12, 1.12, 8.88, 6.66, 5.55, 5.55 }
這應該如下工作:
(對不起,我畫畫很糟糕)。 並且對於使用最高兩對(因此00 00)並填充缺失空間的第二矢量(在這種情況下再次)進行相同的操作。
我認為_mm256_shuffle_pd會以同樣的方式工作。 因此,如果我想要第一個雙倍,我將不得不移動00空間和01空間來正確構造它。
例如:
__m256d a = _mm256_load_pd(&b[0]);
a = _mm256_shuffle_pd(a, a, 0b01000100);
_mm256_store_pd(&b[0], a);
// 1.12 1.12 4.44 3.33
我原以為這會輸出{1.12,1.12,3.33,3.33}。 在我的腦海中,我從第一個向量中獲取00 01(1.12)和00 01 {3.33},從第二個向量中獲取相同的向量,並且它是相同的向量。
我已經嘗試了很多控制面具的組合,我只是無法圍繞如何使用它,也無法找到以我理解的方式解釋它的地方。
所以我的問題是:_mm256_shuffle_pd如何工作? 我怎樣才能得到與_mm_shuffle_ps(a,a,_MM_SHUFFLE(3,0,2,1))相同的結果,包括四個雙打和一個隨機播放(如果可能的話)?
shufps
需要4個元素的所有8位,每個元素有4個可能的源。 因此它沒有空間來增長256位,唯一的選擇是在兩個通道中復制相同的shuffle。
但128位shufpd
只有2個元素,每個元素有2個源,因此2 x 1位。 所以AVX版本總共使用4位,每個通道使用2位。 ( 它不是交叉路口,所以它沒有128位shufps
那么強大 。)
http://felixcloutier.com/x86/SHUFPD.html上有完整的文檔,包含圖表和詳細的偽代碼。 英特爾針對_mm256_shuffle_pd
的內在指南具有相同的偽代碼。
AVX2 http://felixcloutier.com/x86/VPERMPD.html ( _mm256_permute_pd
,又名_mm256_permute4x64_pd
)是車道交叉,並使用其立即完全相同的方式128位shufps
的作用:四個2位選擇。
唯一的交叉2源shuffle是vperm2f128
( _mm256_permute2f128_pd
) ,直到AVX512F引入更精細的粒度vpermt2pd
和vpermt2ps
(和等效的整數shuffle。
AVX1沒有任何小於128位的粒度的交叉混洗,甚至沒有單源版本。 如果你需要一個,你必須用vinsertf128
或vperm2f128
+車道內shuffle來構建它。
因此,使用AVX將3D矢量保持在SIMD矢量中比使用128位矢量的float
更差。 http://fastcpp.blogspot.com/2011/04/vector-cross-product-using-sse-code.html可能比標量更快,但是如果你為SIMD設計數據布局,它會比你做得更糟。
使用單獨的連續x[]
, y[]
和z[]
數組,這樣您就可以並行執行4x交叉產品而不進行改組,並利用FMA指令。 使用SIMD並行執行多個向量,而不是加速單個向量。
請參閱https://stackoverflow.com/tags/sse/info中的鏈接,特別是https://deplinenoise.wordpress.com/2015/03/06/slides-simd-at-insomniac-games-gdc-2015/數據布局問題很好,以及使用SIMD進行矢量化的循環級別。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.