我正在使用大型数组进行计算,对于某些计算,我需要增加堆栈大小!在我的〜/ .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)
答案 0 :(得分:0)
堆栈大小永远不会无限制,所以你仍然会有一些失败。并且您的代码仍然无法移植到具有较小(或正常大小)堆栈的Linux系统。
顺便说一下,你应该解释一下你在运行哪种程序,显示一些源代码。如果使用C ++进行编码,使用标准containers应该会有很多帮助(关于实际的堆栈消耗)。例如,本地(已分配的堆栈)std::vector<int> v(10000);
(而不是int v[10000];
)将其数据分配到堆上(当您从定义它的块退出时,由析构函数释放)
改进程序以避免过多的堆栈消耗会好得多。需要大量的堆栈空间实际上是一个你应该尝试纠正的错误。一个典型的经验法则是call frames小于几千字节(因此在堆上分配更大的数据)。
您可能还考虑使用Boehm conservative garbage collector:您将使用GC_MALLOC
而不是malloc
(并且您将使用GC_MALLOC
堆分配大型数据结构)但是您赢了t必须打扰free
你的(GC-heap allcoated)数据。
答案 1 :(得分:0)
将stacksize设置为无限可能不会对您有所帮助。你正在堆栈中分配一个64MB的块,并且可能不会从顶部填充它,而是从底部填充它。
这一点非常重要,因为操作系统随着您的发展而增加了堆栈。每当它在堆栈段下方检测到页面错误时,它将假定您需要更多空间,并静默插入新页面。但是,地址空间中此触发器区域的大小是有限的,我怀疑它大于64 MB。由于您的索引变量可能位于堆栈中的数组下方,因此访问它们会导致64 MB跳转,从而导致您的进程终止。
只需制作数组allocatable
,添加相应的allocate()
语句,就可以了。