【问题标题】:SSE Documentation and accessingSSE 文档和访问
【发布时间】:2013-04-08 00:42:08
【问题描述】:

目前我正在通过联合访问我的浮点值

typedef union
{
  float v[4];
  _mm128 m;
}SSEFloat;

但是在这个link 我听说性能是损失。 GCC 4 有性能损失吗? float 需要对齐吗?也在联盟?或者这样设置值是否正确

SSEFloat a;
float tmp = 10.0;
a.m = _mm_load1_ps( &tmp );

目前我也找不到英特尔 SSE 内在文档 :( 是否有一个“小”列表 - 速度优化需要知道什么?

【问题讨论】:

标签: c++ c gcc sse


【解决方案1】:

如果您在联合中使用浮点数,编译器可能会输出非 sse 代码来访问它们,这将影响性能。这实际上取决于您的对象使用情况。您可以在包装结构前面添加 _MM_ALIGN16 (__declspec(align(16)) 并覆盖新和删除运算符(如果您正在编写 C++)。检查这个问题:SSE, intrinsics, and alignment

【讨论】:

  • 嘿,所以对于 Speed,使用 Not a Union 会更好吗?如果我分配一个 mm128 数组,我真的需要对齐它们吗?我以为这些元素是对齐的?
  • Union 很好,但是您需要查看生成的代码,因为编译器可能没有按照您的想法进行操作。如果在结构中使用对齐的成员,结构会继承对齐方式(检查:gcc.gnu.org/onlinedocs/gcc-3.2/gcc/Type-Attributes.html
【解决方案2】:

编译器将保证代码将正确执行,但它可能会为了正确性而牺牲性能。由于联合实际上只是增加了访问 4 项浮点向量的各个元素的语法便利,并且 _mm128 对象(从概念上,如果不是实际上)位于寄存器中,我建议您直接使用 _mm128 对象并使用_mm_store_ps_mm_load_ps 系列 API 用于将数据移入和移出对象。

您提供的链接中的注释表明编译器可能会围绕联合进行不良优化,尤其是使用 _mm128s。如果你想确定这一点,你应该在有和没有联合的情况下进行实验。对于 Linux 中的高分辨率时间测量,我推荐使用 pthread_getcpuclockidclock_gettime API。如果可以,请发布您的结果!

一般来说,为了获得最佳性能,请尽可能让编译器简单易行。这意味着将 _mm128 之类的高性能事物排除在联合之类的复杂结构之外,而只需在堆栈上或为它们明确分配的内存中声明它们。

【讨论】:

  • &v 也会降低性能,因为它会阻止编译器注册该值。相反,在将 SSE 元组视为数组时,您应该使用 _mm_store_ps_mm_load_ps
  • 谢谢,@BenVoigt。答案已修改。
  • @Ben Voigt。您应该使用 _mm_set1_ps 而不是 _mm_load_ps,因为 _mm_set1_ps 不会一对一地映射到汇编指令并且由编译器优化。另一方面,_mm_load_ps 是一对一映射到 MOVAPS 指令的。
  • 我认为我们对 OP 的应用程序了解不够,无法知道要使用哪个 API。我修改了我的答案以指向加载和存储 API 系列,应该选择最合适的。
  • @Ben Voigt,我需要对齐 v 吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 2017-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-02
相关资源
最近更新 更多