ARM 固有:在每个复数浮点样本后插入复数零

问题描述 投票:0回答:1

我有以下输入:

[1i+2j], [3i+4j], [5i+6j],...

输出应该是:

[1i+2j], [0i+0j], [3i+4j], [0i+0j], [5i+6j], [0i+0j],...

我写了以下代码:

void Extract (ComplexFloat *pIn, ComplexFloat*pOut, uint32_t N)
{
    ComplexFloat* pSrc = pIn;
    ComplexFloat *pDst = (ComplexFloat*)pOut;
    float32x2_t Zero;
    float32x4_t In, Out;
    float32x2_t HighIn, LowIn;

    Zero = vdup_n_f32 (0);

    //Loop on all input elements 
    for (int n = 0; n < N >> 1; n++)
    {
        In = vld1q_f32((float*)pSrc);
        HighIn = vget_high_f32(In);
        LowIn = vget_low_f32(In);
        Out = vcombine_f32(LowIn, Zero);
        vst1q_f32((float*)pDst, Out);
        pDst += 2;
        Out = vcombine_f32(HighIn, Zero);
        vst1q_f32((float*)pDst, Out);
        pDst += 2;
        pSrc += 2;
    }

}

你能推荐一个性能更好的代码吗?

谢谢你, 兹维卡

arm intrinsics neon
1个回答
0
投票

至少以下应该给出更少的指示:

void interleave(float *src, float *dst, int blocks) {
  uint64x2x2_t data = { vdupq_n_u64(0), vdupq_n_u64(0) };
  do {
     data.val[0] = vreinterpretq_u64_f32(vld1q_f32(src)); src += 4;
     vst2q_u64(reinterpret_cast<uint64_t*>(dst), data); dst += 8;
  } while (--blocks);
}

我们需要将两个相邻的浮点数转换为更宽的 64 位元素,之后我们可以使用

vst2
一次交错 64 位,而无需显式的 zip 指令。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.