加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 与__m256的联合和两个__m128的数组

发布时间:2020-12-16 10:23:10 所属栏目:百科 来源:网络整理
导读:我可以拥有这样的工会吗? union eight_floats_t { __m256 a; __m128 b[2]; }; eight_floats_t eight_floats; 能够即时访问256位寄存器的两个128位部分吗? 编辑:我要求了解这种方法对性能的影响. 解决方法 你当然可以做到这一点. C和C语言允许您这样做.它
我可以拥有这样的工会吗?

union eight_floats_t
  {
    __m256 a;
    __m128 b[2];
  };
  eight_floats_t eight_floats;

能够即时访问256位寄存器的两个128位部分吗?

编辑:我要求了解这种方法对性能的影响.

解决方法

你当然可以做到这一点. C和C语言允许您这样做.它很可能会做你想做的事情.

但是,您使用AVX的事实意味着您关心性能.因此,知道这是SSE程序员陷入的最常见(性能)陷阱之一可能是有用的. (许多人没有注意到)

问题1:

当前的编译器使用存储器位置实现这种联合.所以这是第一个问题,每次从不同的字段访问联合时,它都会强制数据到内存并将其读回.这是一个减速.

以下是MSVC2010为其生成的内容(通过优化):

eight_floats a;
a.a = vecA[0];

__m128 fvecA = a.b[0];
__m128 fvecB = a.b[1];
fvecA = _mm_add_ps(fvecA,fvecB);
vmovaps YMMWORD PTR a$[rbp],ymm0
movaps  xmm1,XMMWORD PTR a$[rbp+16]
addps   xmm1,XMMWORD PTR a$[rbp]
movaps  XMMWORD PTR fvecA$[rbp],xmm1
movss   xmm1,DWORD PTR fvecA$[rbp]

你可以看到它被刷新到内存中.

问题2:

第二次放缓甚至更糟.当您向内存写入内容并立即使用不同的字大小访问它时,您可能会触发存储到加载停顿. (通常大约> 10个周期)

这是因为当前处理器上的加载存储队列通常不是为处理这种(异常)情况而设计的.所以他们通过简单地将队列刷新到内存来处理它.

访问AVX数据类型的上半部分和上半部分的“正确”方法是使用:

> _mm256_extractf128_ps()
> _mm256_insertf128_ps()
> _mm256_castps256_ps128()

和家人.同样对于其他数据类型也是如此.

也就是说,编译器可能足够聪明,无法识别您正在做什么并使用这些指令. (至少MSVC2010没有.)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读