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

How to force pointer returned by new operator to be 32-byte aligned

我在我的程序中使用了 AVX2 intrinsic,并在 class 之一中声明了一个 __m256i 变量,如下所示:

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

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

您可以尝试使用 对齐说明符

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

参见 C++ 标准的 §7.6.2。

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

大多数编译器都有内置的对齐分配函数,比如GCC的aligned_alloc。此函数可以与放置 new 运算符结合使用以创建对齐的对象实例。

例如:

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

注意:使用放置new需要手动调用析构函数,使用delete不行

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

#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