我在我的程序中使用AVX2内在函数,并在其中一个类中声明一个__m256i变量,如下所示:
class A {
protected:
__m256i buffer;
public:
A() {
buffer = _mm256_setzero_si256();
}
};
当我创建A的实例时,如果缓冲区的内存位置不是32字节对齐的,我得到了一个Seg Fault。有没有办法强制新运算符的返回地址或缓冲区的内存地址为32字节对齐?
答案 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节。