簡體   English   中英

shuffle / permute內在函數如何適用於256位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引入更精細的粒度vpermt2pdvpermt2ps (和等效的整數shuffle。

AVX1沒有任何小於128位的粒度的交叉混洗,甚至沒有單源版本。 如果你需要一個,你必須用vinsertf128vperm2f128 +車道內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.

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