如何让我的Fortran程序使用一定数量的RAM?

时间:2013-10-13 18:42:06

标签: memory memory-management fortran

我正在尝试编写一个会占用大量内存的Fortran程序(由于这背后的原因,请参阅本问题末尾的注释)。我这样做是通过分配一个大小为(n,n,n)的3维数组然后解除分配 - 不断增加n直到我的内存不足(这应该在使用~16 GB的内存时发生)。不幸的是,在我看到系统资源达到16 GB之前,好像我的程序内存不足。

以下是我的示例代码:

 1 program fill_mem
 2   implicit none
 3   integer, parameter :: ikind = selected_int_kind(8)
 4   integer, parameter :: rkind = 8
 5
 6   integer(kind = ikind) :: nfiles = 100
 7   integer(kind = ikind) :: n = 1200
 8   integer(kind = ikind) :: i, nn
 9
10   real(kind = rkind), allocatable :: real_arr(:,:,:)
11
12   character(500) :: sysline
13
14
15   call system('echo ''***no_allocation***'' > outfile')
16   call system('ps aux | grep fill_mem.exe >> outfile')
17   !call system('smem | grep fill_mem.exe >> sm.out')
18   allocate(real_arr(n, n, n))
19
20   nn = 100000
21   do i = 1,nn
22     deallocate(real_arr)
23     n = n + 10
24     print*, 'n = ', n
25     allocate(real_arr(n, n, n))
26     call system('echo ''*************'' >> outfile')
27     write(sysline, *) 'allocation', i, '... n = ', n
28
29     write(*, '(f10.5, a)') 100.0*real(i)/real(nn), '%'
30
31     call system(trim(adjustl('echo '//sysline//'>> outfile')))
32     call system('ps aux | grep fill_mem.exe >> outfile')
33   enddo
34
35 end program fill_mem

以下是示例输出:

 1 ***no_allocation***
 2 1000     12350  0.0  0.0  12780   760 pts/1    S+   13:32   0:00 ./fill_mem.exe
 3 1000     12352  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
 4 1000     12354  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
 5 *************
 6 allocation 1 ... n = 1210
 7 1000     12350  0.0  0.0 13853104 796 pts/1    S+   13:32   0:00 ./fill_mem.exe
 8 1000     12357  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
 9 1000     12359  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
10 *************
11 allocation 2 ... n = 1220
12 1000     12350  0.0  0.0 14199096 952 pts/1    S+   13:32   0:00 ./fill_mem.exe
13 1000     12362  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
14 1000     12364  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
15 *************
16 allocation 3 ... n = 1230
17 1000     12350  0.0  0.0 14550804 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
18 1000     12367  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
19 1000     12369  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
20 *************
21 allocation 4 ... n = 1240
22 1000     12350  0.0  0.0 14908284 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
23 1000     12372  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
24 1000     12374  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
25 *************
26 allocation 5 ... n = 1250
27 1000     12350  0.0  0.0 15271572 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
28 1000     12377  0.0  0.0   4400   612 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
29 1000     12379  0.0  0.0   9384   916 pts/1    S+   13:32   0:00 grep fill_mem.exe
30 *************
31 allocation 6 ... n = 1260
32 1000     12350  0.0  0.0 15640720 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
33 1000     12382  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
34 1000     12384  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe
35 *************
36 allocation 7 ... n = 1270
37 1000     12350  0.0  0.0 16015776 956 pts/1    S+   13:32   0:00 ./fill_mem.exe
38 1000     12387  0.0  0.0   4400   616 pts/1    S+   13:32   0:00 sh -c ps aux | grep fill_mem.exe >> outfile
39 1000     12389  0.0  0.0   9384   920 pts/1    S+   13:32   0:00 grep fill_mem.exe

现在,我看到VSZ部分达到~15 GB,所以我假设当我尝试解决更多问题时,它会失败

Operating system error: Cannot allocate memory
Allocation would exceed memory limit

因为没有那么多RAM。为什么RSS远远低于这个?当我实际查看我的系统资源时,我看到大约140 MB被用完了(我在Linux VM中运行它并通过Windows监视系统资源 - 我已经使用了通用的16 GB RAM,所以我应该看到VM内存增加,直到达到16 GB标记 - 对于它的价值,VM具有VT-x /嵌套分页/ PAE / NX,因此它应该像本机操作系统一样使用物理体系结构。)

任何人都可以解释为什么我没有看到我的程序实际上耗尽了整个16 GB的RAM以及如何编写我的代码以保留我在RAM中创建的这些数组 - 充分利用我的可用硬件?

注意:我试图编写一个读取大量内存的示例程序的原因是我正在处理数据,这些数据在ascii文本中占用大约14 GB的空间。在整个程序过程中,我需要处理数据A LOT,所以我想立即读取它,然后在整个程序期间从RAM中引用它。为了确保我正确地执行此操作,我正在尝试编写一个简单的程序,它将在内存中同时存储一个非常大的数组(~15 GB)。

2 个答案:

答案 0 :(得分:7)

(警告:Fortran标准没有说明应该如何实现这一点等等,下面的描述是指Fortran编译器通常如何在当前操作系统上实现。)

当您执行ALLOCATE语句(或等效地,在C,FWIW中调用malloc())时,您实际上并不是在保留物理内存,而只是为您的进程映射地址空间。这就是为什么VSZ上升,而不是RSS。实际上,只有在您第一次访问内存时才会为您的进程保留物理内存(通常以页面大小的粒度,即大多数当前hw上的4 KB)。因此,只有当您开始将一些数据放入阵列时,RSS才会开始攀升。例如。像

这样的陈述
real_arr = 42.

应该将你的RSS提升到VSZ附近。

答案 1 :(得分:1)