gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-02 04:14:45 27 4
gpt4 key购买 nike

我正在尝试编写一个 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

因为没有那么多内存。但为什么 RSS 远远低于这个数字呢?当我实际查看系统资源时,我发现大约 140 MB 被用掉(我在 Linux VM 中运行它并通过 Windows 监视系统资源 - 不过我已经给 GM 提供了 16 GB 的 RAM 来使用,所以我应该看到VM 内存不断增加,直到达到 16 GB 标记 - 就其值(value)而言,VM 具有 VT-x/嵌套分页/PAE/NX,因此它应该使用与 native 操作系统一样的物理架构。

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

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

最佳答案

(注意:Fortran 标准没有说明应该如何实现此类内容等,下面的描述指的是 Fortran 编译器在当前操作系统上通常如何实现。)

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

real_arr = 42.

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

关于memory - 如何让我的 Fortran 程序使用一定量的 RAM?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19348850/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com