0

的文档在这里_alloca()说:

_alloca 例程返回一个指向已分配空间的 void 指针,该指针保证为存储任何类型的对象而适当对齐。

但是,这里说:

_alloca 需要 16 字节对齐,并且还需要使用帧指针。

因此,似乎在第一个参考文献中,他们忘记了大约 32 字节对齐的 AVX/AVX2 类型,例如__m256d.

让我感到困惑的另一件事是第一页说不_alloca()推荐使用,而它建议使用一个可以从堆而不是堆栈分配内存的函数(这在我的多线程应用程序中是不可接受的)。

那么有人可以指出我是否有一些现代的(也许是新的 C/C++ 标准?)对齐堆栈内存分配的方法?

说明1:请不要提供要求数组大小为编译时常量的解决方案。我的函数根据运行时参数值分配可变数量的数组项。

4

4 回答 4

4

使用 _alloca() 过度分配,然后手动对齐。像这样:

const int align = 32;
void *p =_alloca(n + align - 1);
__m256d *pm = (__m256d *)((((int_ptr_t)p + align - 1) / align) * align);

如有必要,请替换const为。#define

于 2017-10-22T20:55:31.970 回答
2

_alloca()当然不是处理堆栈对齐的标准或可移植方式。幸运的是,在 C++11 中,我们得到了alignasstd::aligned_storage. 这些都不会强迫您将任何东西放在堆上,因此它们应该适用于您的用例。例如,要将结构数组与 32 字节边界对齐:

#include <type_traits>

struct bar { int member; /*...*/ };
void fun() {
  std::aligned_storage<sizeof(bar), 32>::type array[16];
  auto bar_array = reinterpret_cast<bar*>(array);
}

或者,如果您只想将堆栈上的单个变量与边界对齐:

void bun() {
  alignas(32) bar b;
}

您还可以使用alignof运算符来获取给定类型的对齐要求。

于 2017-10-24T07:51:57.330 回答
1
于 2017-10-22T21:29:10.250 回答
1

C++11 引入了alignof运算符:

alignof 表达式产生其操作数类型的对齐要求。

您可以按如下方式使用它:

struct s {};
typedef s __attribute__ ((aligned (64))) aligned_s;

std::cout << alignof(aligned_s); // Outputs: 64

注意:如果您的类型的对齐方式大于其大小,编译器将不允许您声明数组类型的数组(在此处查看更多信息):

错误:数组元素的对齐大于元素大小

但是,如果你的类型的对齐小于它的大小,你可以安全地分配数组:

aligned_s arr[32];
-- OR --
constexpr size_t arr_size = 32;
aligned_s arr[arr_size];

支持 VLA 的编译器也将允许那些用于新定义的类型。

于 2017-10-22T20:49:29.087 回答