簡體   English   中英

將復數的實部和虛部解壓縮到單獨的 ymm 寄存器中

[英]Unpacking real and imaginary parts of complex numbers into separate ymm registers

我需要讀取一系列復雜的單精度數字,像 [real1, imag1, real2, imag2, ...] 一樣存儲到 ymm 寄存器中並將它們解壓縮,例如 ymm0 包含 [real1, real2, real3, ... ] 和 ymm1 包含 [imag1, imag2, imag3, ...]。 以下代碼有效,但使用了四次交叉洗牌。 有沒有比我在這里做的更有效的方法來完成這個?

    // the negatives here stand in for imaginary parts
    float _f[] = {1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8};

    int i[] = {0, 2, 4, 6, 1, 3, 5, 7};

    __m256 a = _mm256_loadu_ps(_f);
    __m256 b = _mm256_loadu_ps(_f+8);

    __m256i x = _mm256_loadu_si256((void*)i);

    __m256 c = _mm256_permutevar8x32_ps(a, x);
    __m256 d = _mm256_permutevar8x32_ps(b, x);

    __m256 e = _mm256_permute2f128_ps(c, d, 0x20);
    __m256 f = _mm256_permute2f128_ps(c, d, 0x31);

在此序列的末尾,e 包含實部,f 包含虛部。 我唯一擔心的是,在某些機器上,交叉車道洗牌可能很昂貴。

正如哈羅德在評論中所建議的那樣,這將完成將實部和虛部分離為單獨的向量的工作,但順序不會完全正確。 相反, e將具有 [real1, real5, real2, real6, ...] 而f將具有相應的虛部。 這對於某些應用程序來說可能已經足夠好了,所以我認為值得發布以防其他人發現它有用

    float _f[] = {1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8};

    __m256 a = _mm256_loadu_ps(_f);
    __m256 b = _mm256_loadu_ps(_f+8);

    __m256 c = _mm256_permute_ps(a, 0xd8);
    __m256 d = _mm256_permute_ps(b, 0xd8);

    __m256 e = _mm256_unpacklo_ps(c,d);
    __m256 f = _mm256_unpackhi_ps(c,d);

編輯:而且,正如 Peter Cordes 所指出的,以下更短的解決方案會產生 [real1, real2, real5, real6, real3, real4, real7, real8] 和相應的虛數。

    float _f[] = {1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8};

    __m256 a = _mm256_loadu_ps(_f);
    __m256 b = _mm256_loadu_ps(_f+8);

    __m256 c = _mm256_shuffle_ps(a, b, 0x88);
    __m256 d = _mm256_shuffle_ps(a, b, 0xdd);

暫無
暫無

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

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