堆栈上的G ++ SSE内存对齐

Oct*_*nus 12 c++ assembly memory-management sse alignment

我正在尝试使用Streaming SIMD Extensions重新编写光线跟踪器.我的原始光线跟踪器使用内联汇编和movups指令将数据加载到xmm寄存器中.我已经读过编译器内在函数并不比内联汇编慢得多(我怀疑我甚至可以通过避免未对齐的内存访问来获得速度),而且更加可移植,所以我试图迁移我的SSE代码以使用xmmintrin.h中的内部函数.受影响的主要类是vector,它看起来像这样:

#include "xmmintrin.h"
union vector {
    __m128 simd;
    float raw[4];
    //some constructors
    //a bunch of functions and operators
} __attribute__ ((aligned (16)));
Run Code Online (Sandbox Code Playgroud)

我之前已经读过g ++编译器会自动地沿着内存边界分配结构,这些结构等于最大成员变量的大小,但是这似乎没有发生,并且对齐的属性没有帮助.我的研究表明,这可能是因为我在堆栈上分配了一大堆函数局部向量,并且在x86中无法保证堆栈上的对齐.有没有办法强制这种对齐?我应该提一下,这是在32位机器上的本机x86 Linux下运行,而不是Cygwin.我打算在此应用程序中进一步实现多线程,因此将违规的矢量实例声明为静态不是一种选择.如果需要,我愿意增加矢量数据结构的大小.

Mat*_* M. 6

最简单的方法是std::aligned_storage将对齐作为第二个参数.

如果您还没有,可能需要查看Boost的版本.

然后你可以建立你的联盟:

union vector {
  __m128 simd;
  std::aligned_storage<16, 16> alignment_only;
}
Run Code Online (Sandbox Code Playgroud)

最后,如果它不起作用,你总是可以创建自己的小班:

template <typename Type, intptr_t Align> // Align must be a power of 2
class RawStorage
{
public:
  Type* operator->() {
    return reinterpret_cast<Type const*>(aligned());
  }

  Type const* operator->() const {
    return reinterpret_cast<Type const*>(aligned());
  }

  Type& operator*() { return *(operator->()); }
  Type const& operator*() const { return *(operator->()); }

private:
  unsigned char* aligned() {
    if (data & ~(Align-1) == data) { return data; }
    return (data + Align) & ~(Align-1);
  }

  unsigned char data[sizeof(Type) + Align - 1];
};
Run Code Online (Sandbox Code Playgroud)

它将分配比所需更多的存储空间,但这种方式保证了对齐.

int main(int argc, char* argv[])
{
  RawStorage<__m128, 16> simd;
  *simd = /* ... */;

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

幸运的是,如果检测到对齐是正确的,编译器可能能够优化掉指针对齐的东西.