2013-10-13 51 views
3

我正在嘗試編寫一個會佔用大量內存的Fortran程序(在此背後的推理,請參閱本問題末尾的註釋)。我通過分配一個尺寸爲(n,n,n)的3維數組然後重新分配它 - 繼續增加n直到內存不足(這應在使用〜16 GB內存時發生)。不幸的是,在我看到系統資源高達16 GB之前,似乎我的程序耗盡內存。如何讓我的Fortran程序使用一定數量的RAM?

這裏是我的示例代碼:

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虛擬機中運行此操作系統,並通過Windows監視系統資源 - 儘管如此,我還是給了GM 16 GB的RAM,所以我應該看看虛擬機內存不斷增加,直到達到16 GB的標記爲止,虛擬機具有VT-x /嵌套分頁/ PAE/NX,因此它應該像使用本機操作系統一樣使用物理體系結構)。

任何人都可以解釋爲什麼我沒有看到我的程序實際使用了全部16 GB的RAM,我怎麼能寫我的代碼,以保持這些陣列我創建的RAM - 充分利用我現有的硬件?

注意:我試圖寫一個示例程序讀取大量內存的原因是,我與ASCII文本佔據了大約14 GB的空間數據的工作。在本程序的整個過程中,我將需要處理大量數據,因此我希望一次性讀取所有數據,然後在整個程序期間從RAM中引用它。爲了確保我正確地做到了這一點,我試圖編寫一個簡單的程序,它將一次存儲一個非常大的數組(〜15 GB)。

+0

我將'real_arr'數組更改爲一維,並且(在分配它之後)爲其分配隨機值。我在Windows中看到了我的MEM使用情況......但是現在程序已經在Linux VB中死亡了 - 我沒有看到RAM在Windows中被釋放 - 有什麼想法? – drjrm3

回答

7

(警告:Fortran標準不說如何這樣的事情應該被實現等,下面的描述指的是如何Fortran編譯器上當前的操作系統典型地實現。)

當你執行一個ALLOCATE語句(或者等價地,在C,FWIW中調用malloc()時),實際上並不是預留物理內存,而只是爲你的進程映射地址空間。這就是VSZ上升的原因,但不是RSS。實際上,僅當您第一次訪問內存時(通常以頁面大小粒度,即大多數當前hw上的4 KB),纔會爲您的進程預留物理內存。所以只有當你開始把一些數據放到你的數組裏時,RSS纔會開始攀升。例如。像

real_arr = 42. 

應該將您的RSS升級到VSZ附近。

相關問題