Fortran阵列内存管理
我正在努力优化用Fortran编写的流体流动和传热分析程序。 当我尝试运行越来越大的网格模拟时,我遇到了内存限制问题。 但网格并不是那么大。 典型的CFD代码只能运行500,000个细胞和小花生。 即使当我为我的问题请求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
...
各个领域的解释 - 在这里。 您最感兴趣的是VmData
, VmRSS
, VmHWM
和VmSize
。 您可以使用OPEN()
作为常规文件打开/proc/self/status
,并在Fortran代码中完全处理它。
另请参阅使用ulimit -a
和ulimit -aH
设置的内存限制。 您可能会超出硬虚拟内存大小限制。 如果您通过分布式资源管理器(例如SGE / OGE,Torque / PBS,LSF等)提交作业,请检查是否为该作业请求了足够的内存。