0

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

该程序是用 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)
4

2 回答 2

0

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

顺便说一句,您应该解释您正在运行哪种程序,并显示一些源代码。

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

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

您也可以考虑使用Boehm 保守的垃圾收集器:您将使用GC_MALLOC而不是malloc(并且您将使用 堆分配大型数据结构GC_MALLOC)但您不必费心处理free您的(GC-heap allcoat)数据。

于 2015-08-28T05:23:02.523 回答
0

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

这很重要,因为操作系统会随着您的使用而增加堆栈。每当它检测到堆栈段正下方的页面错误时,它将假定您需要更多空间,并静默插入一个新页面。但是,地址空间内的这个触发区域的大小是有限的,我怀疑它是否大于 64 MB。由于您的索引变量可能位于堆栈上的数组下方,因此访问它们已经执行了 64 MB 的跳转,该跳转会终止您的进程。

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

于 2015-08-31T05:36:17.177 回答