使用 SSE 内在函数复制少量数据的问题

Posted

技术标签:

【中文标题】使用 SSE 内在函数复制少量数据的问题【英文标题】:Issue copying small amount of data using SSE intrinsics 【发布时间】:2018-07-10 16:05:47 【问题描述】:

我在这里查看了类似的问题并尝试使用类似的代码,但在某个地方出错了。顺便说一下,这只是一个学习练习。代码如下:

struct alignas(16) Data

    union
    
      int field1;
      int field2;
      int field3;
      int field4;
      int field5;
      int field6;
      int field7;
      int field8;
      __m128 v[2];
   ;
;

void copy((__m128* __restrict b, const __m128* __restrict a)

    *b++ = *a++;
    *b++ = *a++;


int main(int, char**)

   Data dst=0;
   Data src=0;
   src.field1=1;
   src.field2=500;
   src.field3=200;
   src.field4=393;
   src.field5=29383;
   src.field6=3838;
   src.field7=128484;
   src.field8=111;

   copy(dst.v,src.v);


   std::cout<<" before copy   dst.field1=" << dst.field1 <<" dst.field2=" << dst.field2 << std::endl;
   return 0;

复制前field1和field2都是0,复制后都是111?我对 c++ 相当陌生,所以它似乎将结构的最后 32 位复制到 dst 结构的 64 位上,但不知道为什么?

【问题讨论】:

它没有在任何地方使用.. 只是在玩 sse。谢谢! 【参考方案1】:

您的联合不正确,它有 1 个整数或您的 __m128 数组。 field1field2 等都指向同一个内存。除了最后一个到 field8 之外的所有作业都将被覆盖。

你可以改用这个:

struct alignas(16) Data

    union
    
      int fields[8];
      __m128 v[2];
   ;
;

【讨论】:

@SubliminalBroccoli:或者union struct int field1, field2, ...; ; __m128i v[2]; ; 我忘记了是否允许在联合内部使用匿名结构。顺便说一句,我通常只使用 _mm_load_si128 而不是联合。或者使用足够新的编译器,只需执行dst = src 并让编译器有效地进行结构分配。 (不过,gcc 6 和更早的副本一次只构造一个成员,这通常更糟。请参阅godbolt.org/g/sC94aG.)

以上是关于使用 SSE 内在函数复制少量数据的问题的主要内容,如果未能解决你的问题,请参考以下文章

内在函数和寄存器(SSE)

修改函数以使用 SSE 内在函数

SSE 内在函数优化

将 TBB 与 SSE2 内在函数混合

数组乘法与 sse 内在函数乘法的时序?

了解 SSE 的内在函数如何使用内存