增加堆栈大小

Increase stack size

我正在用巨大的数组进行计算,对于其中的一些计算,我需要增加堆栈大小!在我的 ~/.bashrc 中将堆栈大小设置为无限制(ulimit -s unlimited)有什么缺点吗?

该程序是用 fortran(F77 & F90) 编写的,并与 MPI 并行化。我的一些阵列有超过 2E7 个条目,当我将少量内核与 MPI 一起使用时,它会崩溃并显示 segmentation fault.

数组大小在整个计算过程中保持不变,因此我将它们设置为固定值:

real         ::  p(200,200,400)
integer      ::  ib,ie,jb,je,kb,ke 
...
ib=1;ie=199
jb=2;je=198
kb=2;ke=398
call  SOLVE_POI_EQ(rank,p(ib:ie,jb:je,kb:ke),R)

筹码量从来都不是真正无限的,因此您仍然会遇到一些失败。而且您的代码仍然无法移植到具有较小(或正常大小)堆栈的 Linux 系统。

顺便说一句,你应该解释一下你是哪种程序运行,显示一些源代码。

如果用 C++ 编码,使用标准 containers 应该会有很大帮助(关于实际堆栈消耗)。例如,本地(堆栈分配)std::vector<int> v(10000);(而不是 int v[10000];)在堆上分配其数据(并在您退出定义它的块时由析构函数释放)

最好改进您的程序以避免过多的堆栈消耗。需要大量堆栈 space 确实是一个错误,您应该尝试更正。一个典型的经验法则是 call frames 小于几千字节(因此在堆上分配任何更大的数据)。

您也可以考虑使用 Boehm conservative garbage collector:您将使用 GC_MALLOC 而不是 malloc(并且您将使用 GC_MALLOC 堆分配大型数据结构)但是您不必费心 free 您的(GC 堆全涂层)数据。

将堆栈大小设置为无限制可能对您没有帮助。您正在堆栈上分配 64MB 的块,并且可能不是从顶部填充它,而是从底部填充它。

这很重要,因为 OS 会随着您的进行而增加堆栈。每当它在堆栈段正下方检测到页面错误时,它会假设您需要更多 space,并静默插入一个新页面。不过,您的地址 space 中的触发区域的大小是有限的,我怀疑它是否大于 64 MB。由于您的索引变量可能位于堆栈中数组的下方,因此访问它们已经完成了 64 MB 的跳跃,这会杀死您的进程。

只需创建数组 allocatable,添加相应的 allocate() 语句,就可以了。