[英]Load and store complex floats with Intel intrinsics in C
我正在嘗試使用__m128
向量單位對復雜的浮點數進行一些計算。 使用__m128
我可以存儲兩個complex float
,因為每個復數都包含兩個浮點數,一個實數和一個虛數部分。
到現在為止還挺好。
當我必須將答案“收集”到一個 complex float
時,就會出現我的問題。 假設我有兩個__m128
向量,並且在這兩個向量中存儲了四個復數。 例如,我可以使用_mm_add_ps
內在函數將兩個向量(兩個浮點數和兩個浮點數)加在一起,但是如何將結果向量中的兩個復數“減少”為一個復數(兩個float
s)並將其存儲在一個數組?
同樣,如果我想從數組中獲取一個復數並將其兩次存儲在向量中(第一和第三塊的實部,第二和第四塊的虛部),我該如何做到這一點?
如果要在其上使用SIMD,請不要首先以交錯/打包格式存儲復數。 將實部和虛部存儲在單獨的陣列中,因此您可以並行進行四個復數乘法,而無需任何改組(或像HSUBPS這樣的慢速水平運算)。
要直接回答這個問題:做一個水平求和的第一階段 :將高64降到另一個向量的低64(使用_mm_movehl_ps
),然后是_mm_add_ps
,如我對該問題的回答所示。
然后,您可以MOVLPS來存儲低2個浮點數: void _mm_storel_pi (__m64 *p, __m128 a)
。 看起來您需要進行煩人的強制轉換才能使用它:/ MOVSD也可以工作,但是需要多一個字節進行編碼。
同樣,如果我想從數組中提取一個復數並將其存儲在向量中兩次
使用MOVDDUP廣播來自存儲器或另一個寄存器的64位。 您需要進行一些強制轉換才能使用內部函數,但這很好(它們不會編譯為任何指令,並且對float
數據使用MOVDDUP之類的double
指令不會對任何現有CPU造成不利影響):
__m128d _mm_loaddup_pd(double const * dp);
__m128d _mm_movedup_pd(__m128d a);
至少它具有固有的負載,這與PMOVZX不同( 此設計缺陷是我的主要固有函數之一 )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.