【问题标题】:SSE to Neon (_mm_movelh_ps)SSE 到霓虹灯 (_mm_movelh_ps)
【发布时间】:2017-03-07 10:20:25
【问题描述】:

我正在将一些 SSE 代码移动到 Neon,但我找不到任何与 _mm_movelh_ps 等效的代码。我用谷歌搜索了很多东西……我错过了什么吗?是否有任何 Neon 功能可以做同样的事情,否则我将不得不在 CPU 上实现它(不理想)。

提前致谢!

【问题讨论】:

    标签: c sse neon


    【解决方案1】:

    SSE 有 128 位向量寄存器 ("xmmN")。 _mm_movelh_ps() 从向量寄存器的低 64 位传输到向量寄存器的高 64 位。

    ARM32 NEON 具有 64 位向量寄存器 ("dN")。两个连续的向量寄存器,第一个为偶数,可以组合成一个 128 位的向量寄存器("qN")。

    要在 ARM32 NEON 中获得 _mm_movelh_ps 的功能,可以使用普通的 64 位向量移动。

    #include <immintrin.h>
    __m128 foo(__m128 a, __m128 b)
    {
      return _mm_movelh_ps(a, b);
    }
    

    等价于下面的 gcc 向量内在函数

    typedef float v4sf __attribute__((vector_size(16)));
    typedef unsigned v4ui __attribute__((vector_size(16)));
    v4sf bar(v4sf a, v4sf b)
    {
      return __builtin_shuffle(a, b, (v4ui){0, 1, 4, 5});
    }
    

    在我的 gcc 4.8.4 上两者都编译成相同的代码:

    movlhps %xmm1, %xmm0
    ret
    

    不幸的是,用于 ARM32 NEON 的 gcc 4.9.2 为此产生了可笑错误代码:

        vldr    d16, .L2
        vldr    d17, .L2+8
        vtbl.8  d18, {d0, d1, d2, d3}, d16
        vtbl.8  d19, {d0, d1, d2, d3}, d17
        vmov    q0, q9  @ v16qi
        bx      lr
    

    所以你可能需要使用 NEON-intrinsics:

    #include <arm_neon.h>
    
    float32x4_t foo(float32x4_t a, float32x4_t b)
    {
      return vcombine_f32(vget_low_f32(a), vget_low_f32(b));
    }
    

    编译为预期的简单移动指令:

        vmov    d1, d2  @ v2sf
        bx      lr
    

    【讨论】:

    • 你打败了我。在发布之前,我正在启动我的 Raspberry Pi 以进行验证! :)
    • @Vallentin:这就是我一直在运行的原因 ;-)
    • 这是一个非常古老的编译器。有没有办法升级?你建立在什么主机上?也许我可以找到你的链接。我不能放弃发布链接到更好的编译器的机会。
    • @sh1:嗯,x86-64 gcc 4.8.4 是我迫切需要放弃的古代 Mint 版本的默认设置。 ARM gcc 4.9.2 是 Raspian 的默认版本,并且是 AFAIK 提供的最新版本。在gcc.godbolt.org 上,gcc 5.4 生成相同的代码,而 5.4.1 失败得更可怕(似乎它没有正确的 NEON 标头?)。
    • 我在 google 上搜索了一下,看起来 Stretch 中的 GCC 6.1 即将推出,所以也许只是坐等一下。但是,是的,我在 NEON 内在函数之外的 GCC 向量支持方面也遇到了很多麻烦,我对这个问题的持续存在并不完全感到惊讶。您也可以通过Clang nightlies 试试运气。
    猜你喜欢
    • 2013-11-07
    • 2015-02-14
    • 1970-01-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多