【问题标题】:Broadcast one arbitrary element of __m128 vector广播 __m128 向量的任意一个元素
【发布时间】:2017-09-12 19:21:58
【问题描述】:

我需要广播 __m128 向量的任意一个元素。 比如第二个元素:

__m128 a = {a0, a1, a2, a3};
__m128 b = {a1, a1, a1, a1};

我知道有内在函数 _mm_set1_ps(float) 和 _mm_broadcast_ss(float*)。 但是这些内在函数可以从常用的内存寄存器中加载值。 有没有办法从另一个向量寄存器设置标量值?

【问题讨论】:

    标签: c++ x86 sse simd sse2


    【解决方案1】:

    我认为你必须看到 _mm_shuffle_epi32()。使用下一个辅助函数将很容易:

    #include <emmintrin.h>
    
    template <int index> inline __m128 Broadcast(const __m128 & a)
    {
        return _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(a), index * 0x55));
    }
    
    int main()
    {
        __m128 a = {a0, a1, a2, a3};
        __m128 b = Broadcast<1>(a);
        return 0;
    }
    

    【讨论】:

    • 谢谢。这就是我想要的。
    【解决方案2】:

    你可以像这样使用_mm_shuffle_ps

    b = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1,1,1,1));
    

    【讨论】:

    • 谢谢。您的解决方案得到相同的结果。我现在不知道哪个是最好的。
    • @Alex 通常是这个,只要有区别。使用错误输入的指令可能会导致额外的绕过延迟,具体取决于上下文和 µarch。
    • 这条指令的缺点是它可能需要额外的寄存器移动(但是,这可能会或可能不会有任何影响)
    • @chtz 我同意,不知怎的,pshufd 没有 __m128 内在属性
    • 好吧,some research 证明这个答案毕竟是要走的路。在浮点数和整数之间切换几乎会刷新整个管道
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 1970-01-01
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多