如何强制new运算符返回的指针为32字节对齐

时间:2017-01-01 19:41:34

标签: c++ new-operator avx2

我在我的程序中使用AVX2内在函数,并在其中一个类中声明一个__m256i变量,如下所示:

class A {
protected:
    __m256i buffer;
public:
    A() { 
        buffer = _mm256_setzero_si256();
    }
};

当我创建A的实例时,如果缓冲区的内存位置不是32字节对齐的,我得到了一个Seg Fault。有没有办法强制新运算符的返回地址或缓冲区的内存地址为32字节对齐?

3 个答案:

答案 0 :(得分:3)

根据评论,因为alignas说明符似乎不起作用:

大多数编译器都有内置的对齐分配功能,例如GCC' aligned_alloc。此函数可与placement new运算符组合以创建对齐的对象实例。

例如:

void* ptr = aligned_alloc(32, sizeof(A));
A* a = new(ptr) A;

注意:使用展示位置new需要手动调用析构函数,使用delete无法正常工作

答案 1 :(得分:2)

我认为你不需要新的位置:

#include <cstdlib>
#include <new>

using size_t = ::std::size_t;

template <size_t ALIGNMENT>
struct alignas(ALIGNMENT) AlignedNew {
  static_assert(ALIGNMENT > 0, "ALIGNMENT must be positive");
  static_assert((ALIGNMENT & (ALIGNMENT - 1)) == 0,
      "ALIGNMENT must be a power of 2");
  static_assert((ALIGNMENT % sizeof(void*)) == 0,
      "ALIGNMENT must be a multiple of sizeof(void *)");
  static void* operator new(size_t count) { return Allocate(count); }
  static void* operator new[](size_t count) { return Allocate(count); }
  static void operator delete(void* ptr) { free(ptr); }
  static void operator delete[](void* ptr) { free(ptr); }

 private:
  static void* Allocate(size_t count) {
    void* result = nullptr;
    const auto alloc_failed = posix_memalign(&result, ALIGNMENT, count);
    if (alloc_failed)  throw ::std::bad_alloc();
    return result;
  }
};

现在只需继承AlignedNew<32>

另请参阅此提案,该提案已被C ++ 17接受:Dynamic memory allocation for over-aligned data

答案 2 :(得分:0)

您可以尝试使用 alignment-specifier

class A {
protected:
    __m256i alignas(32) buffer;
    ...
};

参见C ++标准的第7.6.2节。