增加堆栈大小以使用alloca()
Increase stack size to use alloca()?
这是两个重叠的问题—我希望尝试为大型数组分配alloca(),而不是在堆上分配动态大小的数组。这样我就可以在不进行堆分配的情况下提高性能。然而,我得到的印象是堆栈大小通常相当小?为了充分利用alloca()而增加堆栈的大小有什么缺点吗?我拥有的RAM越多,我就能按比例增加堆栈大小吗?
EDIT1:最好是Linux
堆栈大小(默认情况下)在大多数unix-y平台上为8MB,在Windows上为1MB(也就是说,因为Windows有一种确定性的方式来恢复堆栈外问题,而unix-y平台通常抛出一个通用的SIGSEGV
信号)。
如果您的分配很大,那么在堆上分配与在堆栈上分配之间不会有太大的性能差异。当然,每次分配堆栈的效率会稍微高一些,但是如果分配的数量很大,那么分配的数量可能会很小。
如果你想要一个更大的类似堆栈的结构,你可以自己写一个分配器,它从malloc中获取一个大块,然后以类似堆栈的方式处理分配/释放。
#include <stdexcept>
#include <cstddef>
class StackLikeAllocator
{
std::size_t usedSize;
std::size_t maximumSize;
void *memory;
public:
StackLikeAllocator(std::size_t backingSize)
{
memory = new char[backingSize];
usedSize = 0;
maximumSize = backingSize;
}
~StackLikeAllocator()
{
delete[] memory;
}
void * Allocate(std::size_t desiredSize)
{
// You would have to make sure alignment was correct for your
// platform (Exercise to the reader)
std::size_t newUsedSize = usedSize + desiredSize;
if (newUsedSize > maximumSize)
{
throw std::bad_alloc("Exceeded maximum size for this allocator.");
}
void* result = static_cast<void*>(static_cast<char*>(memory) + usedSize);
usedSize = newUsedSize;
return result;
}
// If you need to support deallocation then modifying this shouldn't be
// too difficult
}
程序主线程获得的默认堆栈大小是特定于编译器(和/或特定于操作系统)的东西,您应该查看适当的文档以了解如何扩大堆栈。
您可能无法将程序的默认堆栈扩展到任意大的大小。
但是,正如前面所指出的,您可以在运行时创建一个具有您想要的堆栈大小的线程。
在任何情况下,alloca()
与一次分配的大缓冲区相比没有太大的好处。您不需要多次释放和重新分配它。
alloca()
和new
/malloc()
之间最重要的区别是,当您从当前函数返回时,alloca()
分配的所有内存将消失。
alloca()
只适用于小型临时数据结构。
它只对小数据结构有用,因为大数据结构会破坏堆栈的缓存局部性,这会给你带来相当大的性能影响。对于作为局部变量的数组也是如此。
仅在非常特殊的情况下使用alloca()
。如果不确定,请不要使用。
一般规则是:不要将大数据结构(>= 1k)放在堆栈上。堆栈不能扩展。这是一个非常有限的资源。
回答第一个问题:相对于堆大小,堆栈大小通常较小(在大多数Linux应用程序中都是如此)。
如果您计划的分配相对于实际默认堆栈大小较大,那么我认为最好使用堆中的动态分配(而不是尝试增加堆栈大小)。使用内存的成本(填充内存、读取内存、操作内存)可能会远远超过分配内存的成本。在这种情况下,您不太可能通过从堆栈中进行分配来看到可衡量的好处。
- 算法问题:查找从堆栈中弹出的所有序列
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么调用堆栈数组会导致内存泄漏
- gdb错误:Backtrace已停止:上一帧与此帧相同(堆栈已损坏?)
- 在 leetcode 上提交解决方案时出现堆栈缓冲区溢出错误
- 我的 int main() 中出现堆栈溢出错误
- 堆栈和队列是否像C++中的数组一样传递?
- 拥有映射的现代方法,该映射可以指向或引用已在堆栈上分配的不同类型的数据
- 为什么 STL 容器适配器堆栈中的 top 返回常量引用?
- 从堆栈分配的原始指针构造智能指针
- 在函数范围内在堆栈上分配的数组在离开函数时是否总是被释放?
- 堆栈中大小变量输入错误 (C++)
- 堆栈问题(平衡表达式问题集)
- C++ 在堆栈中包含多态属性的类对象存储
- 用于解析 win64 堆栈跟踪的命令行客户端(可以访问符号服务器)
- 如果使用alloca在内联函数中的堆栈上分配变量,那么在内联函数返回后,其引用是否有效
- 多次调用alloca()会导致堆栈的连续部分
- 函数包装中的堆栈分配/函数中的alloca
- 增加堆栈大小以使用alloca()