【问题标题】:Increase stack size增加堆栈大小
【发布时间】:2015-11-22 16:26:03
【问题描述】:

我正在使用巨大的数组进行计算,对于其中一些计算,我需要增加堆栈大小!在我的 ~/.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)

【问题讨论】:

  • 你运行的是什么软件?使用哪种编程语言?你在编码吗?您能否展示一些源代码(以便编辑您的问题以改进它)?
  • Fortran77、Fortran90、Fortran2006?显示处理(和分配)巨大数组的实际代码。

标签: linux fortran mpi stack-size


【解决方案1】:

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

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

只要让你的数组allocatable,加上对应的allocate()语句,就可以了。

【讨论】:

  • 我一直以为allocatable数组是在运行时数组大小发生变化时使用的?我的从一开始就固定,并且在整个计算过程中保持相同的大小!
  • 您可以使用allocatable 创建具有动态大小的数组,但它也有助于避免大的堆栈分配。可分配数组总是分配在没有堆栈限制的堆上。如果您将编译时间常数传递给 allocate() 语句,它不会抱怨;-)
【解决方案2】:

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

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

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

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

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

【讨论】:

  • 我编辑了我的问题!我的代码最重要的是减少计算时间。数组始终保持相同的大小,因此我将其设置为固定值!
  • 在堆中分配数组应该不会改变太多的 CPU 时间。
  • 好的,但是如果我在创建它们时将其设置为固定值,我看不出有什么好处。还是p(ib:ie,jb:je,kb:ke) 有问题?
  • 可能是编译器夜间在堆栈上创建临时数组时出现的问题(请查阅编译器的文档以查看是否有可能将数组放入堆中)。
猜你喜欢
  • 2010-11-24
  • 2013-12-24
  • 2011-09-29
  • 2012-02-10
  • 2017-03-02
  • 1970-01-01
  • 1970-01-01
  • 2013-03-15
相关资源
最近更新 更多