在堆栈上分配对齐的内存,如_alloca
Allocate aligned memory on the stack like _alloca
_alloca()
的文档显示如下:
然而,这里说:
_alloca需要16字节对齐,此外还需要使用帧指针。
因此,在第一次引用中,他们似乎忘记了32字节对齐的AVX/AVX2类型,如__m256d
。
另一件让我困惑的事情是,第一页说_alloca()
不推荐使用,而它建议使用一个可能从堆而不是堆栈分配内存的函数(这在我的多线程应用程序中是不可接受的)。
那么,有人能告诉我,是否有一些现代的(也许是新的C/C++标准?)对齐堆栈内存分配的方法吗?
澄清1:请不要提供要求数组大小为编译时间常数的解决方案。我的函数根据运行时参数值分配可变数量的数组项。
用_alloca()过度分配,然后手动对齐。像这样:
const int align = 32;
void *p =_alloca(n + align - 1);
__m256d *pm = (__m256d *)((((int_ptr_t)p + align - 1) / align) * align);
如有必要,用#define
替换const
。
_alloca()
当然不是处理堆栈对齐的标准或可移植方式。幸运的是,在C++11中我们得到了alignas
和std::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
运算符来获取给定类型的对齐要求。
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的编译器也将允许新定义的类型使用VLA。
"现代"方式是:
不要在堆栈上进行可变长度分配
在你的问题中——想要在堆上分配,但又不这么做——我假设你分配的内存可能超过了一些小的编译时常量。在这种情况下,您只需要使用alloca()
调用来破坏堆栈。相反,使用线程安全的内存分配器。我相信GitHub上有这样的库(最坏的情况下,你可以用全局互斥来保护分配调用,尽管如果你需要很多互斥,这会很慢)。
另一方面,如果你事先知道分配大小的上限是多少——只需在线程本地存储中预先分配那么多内存;或者使用固定大小的本地数组(将在堆栈上分配)。
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 类型总是使用其大小存储在内存中吗
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 何时使用alloca为类成员释放内存