Fortran 阵列内存管理



我正在努力优化用Fortran编写的流体流动和传热分析程序。 当我尝试运行越来越大的网格模拟时,我遇到了内存限制问题。 不过,网格并不是那么大。 只有 500,000 个单元格和小花生即可运行典型的 CFD 代码。 即使我为我的问题请求 80 GB 内存,它也由于虚拟内存不足而崩溃。

我对哪些数组占用了所有内存有一些猜测。 特别是分配给(28801,345600)。 如果我的计算错误,请纠正我,但双精度数组是每个值 8 位。 所以这个数组的大小是 28801*345600*8=79.6 GB?

现在,我认为这个数组的大部分在整个计算过程中最终都是零,所以我们不需要存储它们。 我想我可以更改解决方案算法,只将非零值存储在一个更小的数组中。 但是,我想确保我正在寻找正确的数组来减小大小。 所以首先,我是否正确计算了上面的数组大小? 其次,有没有办法让 Fortran 在运行时以 MB 或 GB 为单位显示数组大小? 除了打印出最占用内存的数组之外,我还有兴趣了解代码的内存需求在运行时如何变化。

内存使用在具有虚拟内存的系统上是一个定义相当模糊的概念。您可以分配大量内存(较大的虚拟内存大小),但实际上只有一小部分内存被主动使用(小型驻留集大小 - RSS)。

Unix 系统提供getrusage(2)系统调用,该调用返回有关调用线程/进程/进程子级正在使用的系统资源量的信息。特别是,它提供了自进程启动以来达到的RSS的最大最小值。您可以编写一个简单的 Fortran 可调用帮助程序 C 函数,该函数将调用getrusage(2)并返回rusage结构的ru_maxrss字段的值。

如果您在 Linux 上运行并且不关心可移植性,那么您可以打开并从 /proc/self/status 中读取。它是一个简单的文本伪文件,其中包含几行有关进程虚拟内存使用情况的统计信息:

...
VmPeak:     9136 kB
VmSize:     7896 kB
VmLck:         0 kB
VmHWM:      7572 kB
VmRSS:      6316 kB
VmData:     5224 kB
VmStk:        88 kB
VmExe:       572 kB
VmLib:      1708 kB
VmPTE:        20 kB
...

各个领域的解释 - 在这里。你最感兴趣的是VmDataVmRSSVmHWMVmSize。您可以使用OPEN()/proc/self/status作为常规文件打开,并完全在Fortran代码中处理它。

另请参阅使用 ulimit -aulimit -aH 设置了哪些内存限制。您可能超出了硬虚拟内存大小限制。如果通过分布式资源管理器(例如 SGE/OGE、Torque/PBS、LSF 等)提交作业,请检查是否为作业请求了足够的内存。

最新更新