在 __mm128 寄存器中设置最后一个值

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

所以我有一组具有混合值的数据用于打包目的,如下所示:

{(Point_x, Point_y, Point_z, 标量),(Point_x, Point_y, Point_z, 标量),(Point_x, Point_y, Point_z, 标量),...}

其中每个 Point_x、Point_y、Point_z 和 Scalar 都是 32 位浮点数。

因此,我可以加载对齐的每个点,但我需要将点 x,y,z 移动到自己的寄存器中进行操作,然后将最后一个值设置为

1.f
寄存器中的
__mm128
(其中标量将会)。使用什么指令将寄存器中的最后一个值设置为
1.f
并保持其他值不变?

目前我正在做:

    __m128 rPointMixed = _mm_load_ps( (float*)pPoint );
    __m128 rOne =_mm_set1_ps(1.f);
    __m128 rPoint = _mm_blend_ps(rPointMixed,rOne,0x8);

但可能不是最有效的解决方案,我对 sse4/avx/avx2 指令很好,尽管如果有真正有效的方法的话

struct Vec4f
{
    float x;
    float y;
    float z;
    float scalar;
};

Vec4f vData[10000];

//in reality this loop is unrolled to do 8 at a time, but rolled up for simplicity sake
for( int i = 0; i < 10000; ++i)
{
    __m128 rPointData = _mm_load_ps( (float*)vData[i] );
    //math there where it permutes the scalar and does math with it

   //4 just cause it is the last value?
   __m128 rPoint = [unknownIntrinsic](rPointData ,1.f, 4); //?
  
  //point math here

}

感谢您提前的帮助

c++ simd sse avx
1个回答
0
投票

除非有一条指令的吞吐量比

blendps
(Intel 上0.33 CPI)更好,否则你所做的已经是理想的了。

请注意,您实际上不需要为循环的每次迭代调用

_mm_set1_ps(1.f)
(因此您的“未知内在函数”实际上只是
_mm_blend_ps
),因为
rOne
是常数。然而,启用优化后,大多数编译器都会足够聪明,在循环之前只执行一次。


旁注:对于 ISA 设计者来说,允许指令仅修改寄存器的一部分通常不是一个好主意,因为这会创建对先前值的(通常是不必要的)依赖。

© www.soinside.com 2019 - 2024. All rights reserved.