【发布时间】:2011-06-25 08:18:26
【问题描述】:
我正在尝试使用 Streaming SIMD Extensions 重新编写光线追踪器。我最初的光线追踪器使用内联汇编和 movups 指令将数据加载到 xmm 寄存器中。我已经读过编译器内在函数并不比内联汇编慢很多(我怀疑我什至可以通过避免未对齐的内存访问来提高速度),并且更便携,所以我正在尝试迁移我的 SSE 代码以使用 xmmintrin.h 中的内在函数.受影响的主要类是向量,它看起来像这样:
#include "xmmintrin.h"
union vector {
__m128 simd;
float raw[4];
//some constructors
//a bunch of functions and operators
} __attribute__ ((aligned (16)));
我之前读过 g++ 编译器会自动沿内存边界分配结构,该结构等于最大成员变量的大小,但这似乎没有发生,并且对齐的属性没有帮助。我的研究表明,这很可能是因为我在堆栈上分配了一大堆函数局部向量,而 x86 不能保证堆栈上的对齐。有没有办法强制这种对齐?我应该提一下,这是在 32 位机器上的本机 x86 Linux 下运行的,而不是 Cygwin。我打算在这个应用程序中进一步实现多线程,因此将有问题的向量实例声明为静态不是一种选择。如果需要,我愿意增加矢量数据结构的大小。
【问题讨论】:
-
如果您有支持
std::aligned_storage的最新版本的 g++,您可以通过一种可移植的方式获得对齐存储,并且也可以在其他编译器上运行 -
如果绕过并直接使用 __m128 会怎样?这有什么改变吗?
-
完全绕过联合使得访问单个成员变得更加痛苦。我也有一个 vectorpacket 类,它从 SSE 中获得比标准向量更多的好处,但作为一个例子,我的基准测试表明,我可以更快地串行添加单个点积的成员,而不是反复改组寄存器到在我的 SSE 块中添加时添加。我不熟悉
std::aligned_storage;也就是说,我的机器有 g++ 4.4.3,但是我希望能够在锁定到 3.4.6 的第二台机器上运行它。 -
software.intel.com/en-us/forums/showthread.php?t=63876 注意他们将数组转换为 m128 类型。您可以类似地将 m128 转换为数组。
-
@Anycorn:不,
(float*)my_m128是不安全的。 Intel 向量类型的 may-alias-anything 属性只适用于一种方式,即如何使用char*访问任何内容,但不能保证使用int*访问char[]是安全的。 (它在 MSVC 中是安全的,类似于gcc -fno-strict-aliasing,但在其他编译器中,您应该使用联合或随机内部函数来访问向量的元素。)请参阅 print a __m128i variable 以获取示例。
标签: c++ assembly memory-management alignment sse