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