2015-08-28 147 views
0

我正在做巨大数组的计算,对于这些计算中的一些,我需要增加堆栈大小!在我的〜/ .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

Fortran77,Fortran90,Fortran2006?显示处理(并分配)巨大数组的实际代码。 –

回答

0

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

这很重要,因为操作系统随着您的增长而增长。只要它检测到堆栈段下方的页面错误,就会认为您需要更多空间,并静静地插入新页面。尽管如此,你的地址空间中这个触发区的大小是有限的,我怀疑它大于64 MB。由于您的索引变量可能位于堆栈之下的数组之下,因此访问它们已经导致64 MB跳跃,从而导致您的进程崩溃。

只要让你的数组allocatable,添加相应的allocate()声明,你应该没问题。

+0

我一直认为在运行时数组大小发生变化时会使用'allocatable'数组吗?我从一开始就修好了,在整个计算过程中保持不变! – chi86

+0

您可以使用'allocatable'来创建动态大小的数组,但它也可以避免大的堆栈分配。一个可分配数组总是分配在没有堆栈限制的堆上。而'allocate()'语句不会抱怨,如果你传递一个编译时间常量;-) – cmaster

+0

好吧,这是有道理的,那么我会这样做!谢谢 – chi86

0

堆栈大小是从来没有真正无限的,所以你还是会有一些故障。而且你的代码仍然不能移植到小型(或普通大小)堆栈的Linux系统上。

顺便说一句,你应该说明你正在运行哪种程序,显示一些源代码。

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

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

你也许还可以考虑使用Boehm conservative garbage collector:你会使用GC_MALLOC代替malloc(你会堆上分配使用GC_MALLOC大数据结构),但你不会费心去free你(GC-堆allcoated)数据。

+0

我编辑了我的问题!我的代码最重要的是减少计算时间。数组总是保持相同的大小,因此我将它设置为固定值! – chi86

+0

分配堆中的数组不应该改变CPU的时间。 –

+0

好吧,但我没有看到优势,如果我创建它们时将其设置为固定值。或者是'p(ib:ie,jb:je,kb:ke)'这个问题? – chi86