Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Memory management Fortran阵列内存管理_Memory Management_Fortran - Fatal编程技术网

Memory management Fortran阵列内存管理

Memory management Fortran阵列内存管理,memory-management,fortran,Memory Management,Fortran,我正致力于优化用Fortran编写的流体流动和传热分析程序。当我尝试运行越来越大的网格模拟时,我遇到了内存限制问题。不过,网格并没有那么大。一个典型的CFD代码只有500000个单元格和小花生才能运行。即使当我为我的问题请求80 GB内存时,它也会因为虚拟内存不足而崩溃 我有一些猜测是什么数组占用了所有的内存。其中一项特别分配给(28801345600)。如果我的计算有误,请纠正我,但双精度数组的每个值为8位。那么这个数组的大小是28801*345600*8=79.6GB 现在,我认为这个数组的

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

我有一些猜测是什么数组占用了所有的内存。其中一项特别分配给(28801345600)。如果我的计算有误,请纠正我,但双精度数组的每个值为8位。那么这个数组的大小是28801*345600*8=79.6GB


现在,我认为这个数组的大部分在整个计算过程中都是零,所以我们不需要存储它们。我想我可以改变求解算法,只将非零值存储在更小的数组中。但是,我想确保我正在寻找合适的阵列来减小大小。首先,我是否正确计算了上面的数组大小?第二,有没有办法让Fortran在运行时以MB或GB显示数组大小?除了打印出内存最密集的数组外,我还想了解代码的内存需求在运行时是如何变化的。

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

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

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

。。。
峰值:9136 kB
虚拟机大小:7896 kB
VmLck:0 kB
VmHWM:7572 kB
VmRSS:6316KB
VmData:5224KB
VmStk:88 kB
VmExe:572 kB
VmLib:1708kb
VmPTE:20KB
...
各字段的说明-。您最感兴趣的是
VmData
VmRSS
VmHWM
VmSize
。您可以使用
open()
以常规文件的形式打开
/proc/self/status
,并完全在Fortran代码中处理它


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

运行此操作的机器上实际有多少内存?此外,您错误地认为双精度是8字节,而不是8位。结果是大约74.16GB的数据(1024次方,而不是1000次方)。另外,假设您正在处理4天的数据(345600秒=60*60*24*4),这是否正确?Mike,这是在一个群集上运行的,每个节点可以请求多达96 GB的内存。很抱歉字节与位的混淆,谢谢你澄清了这一点,但我的判断是正确的,所以数组大小肯定是个问题。不,345600与模型网格中的单元数有关,与时间无关。@user104629:原因之一可能是它无法分配一个80 GB内存的连续数组。在我看来,如果在一个0.5 mCell的CFD模型中需要这样一个大数组,那就大错特错了。当然可以。正如我所怀疑的,问题在于压力系数矩阵中存储了非零条目。TotalView显示此阵列消耗80 GB。我通过使用压缩存储格式修复了这个问题。TotalView还显示了另外两个非常大的阵列,每个阵列占用10GB的空间,在代码中什么也不做。消除这些问题使我能够将内存使用量从100 GB以上减少到2.5 GB。很酷,谢谢你的建议。可移植性不是我关心的问题,所以我想我将使用/proc/self/status路径来观察内存使用情况。ulimit-a表明虚拟内存是无限的。有人还向我建议,可以使用DDT和TotalView来检查代码内存被占用的位置。TotalView有一些高级内存调试功能,但我没有广泛使用。至少任何调试器都可以向您显示内存错误发生的位置。最后可能会出现与内存耗尽不同的情况。我突然想到——集群节点交换是否更少?如果是的话,您可能正在耗尽整个系统内存,Linux OOM杀手可能正在启动…我尝试了TotalView,它有很多提示。我将不得不花一些时间学习如何使用它们。使用“heap status source report”(堆状态源报告)可以显示我认为是消耗大量内存的数组。在使用调试器运行时,我注意到的另一个奇怪行为是,几乎每次我暂停时,它都会在特定的数组初始化时停止,例如“array=0.0”。这是我应该进一步调查的吗?我不知道交换问题,但我想我希望设计代码以避免交换,对吗?分配数组只保留一部分虚拟内存。归零实际上是从物理内存提交页面。将70+GB归零需要一些时间,特别是在其他内存不足的情况下