2015-08-28 242 views
0

我正在做巨大數組的計算,對於這些計算中的一些,我需要增加堆棧大小!在我的〜/ .bashrc中將堆棧大小設置爲無限制(ulimit -s unlimited)有什麼不利嗎?增加堆棧大小

該程序使用Fortran編寫(F77 & F90)並與MPI並行化。我的一些陣列有超過2E7條目,當我使用MPI的少量內核時,它會與segmentation fault崩潰。

數組大小保持在整個計算同樣,因此我設置好的他們修正值:

real   :: p(200,200,400) 
integer  :: ib,ie,jb,je,kb,ke 
... 
ib=1;ie=199 
jb=2;je=198 
kb=2;ke=398 
call SOLVE_POI_EQ(rank,p(ib:ie,jb:je,kb:ke),R) 
+0

你正在運行什麼樣的軟件?在哪種編程語言?你在編碼嗎?你能否顯示一些源代碼(所以**編輯你的問題**以改善它)? –

+0

Fortran77,Fortran90,Fortran2006?顯示處理(並分配)巨大數組的實際代碼。 –

回答

0

將堆棧大小設置爲無限可能不會對您有所幫助。您正在堆棧中分配64MB的大塊,並且可能不會從頂部填充,而是從底部填充。

這很重要,因爲操作系統隨着您的增長而增長。只要它檢測到堆棧段下方的頁面錯誤,就會認爲您需要更多空間,並靜靜地插入新頁面。儘管如此,你的地址空間中這個觸發區的大小是有限的,我懷疑它大於64 MB。由於您的索引變量可能位於堆棧之下的數組之下,因此訪問它們已經導致64 MB跳躍,從而導致您的進程崩潰。

只要讓你的數組allocatable,添加相應的allocate()聲明,你應該沒問題。

+0

我一直認爲在運行時數組大小發生變化時會使用'allocatable'數組嗎?我從一開始就修好了,在整個計算過程中保持不變! – chi86

+0

您可以使用'allocatable'來創建動態大小的數組,但它也可以避免大的堆棧分配。一個可分配數組總是分配在沒有堆棧限制的堆上。而'allocate()'語句不會抱怨,如果你傳遞一個編譯時間常量;-) – cmaster

+0

好吧,這是有道理的,那麼我會這樣做!謝謝 – chi86

0

堆棧大小是從來沒有真正無限的,所以你還是會有一些故障。而且你的代碼仍然不能移植到小型(或普通大小)堆棧的Linux系統上。

順便說一句,你應該說明你正在運行哪種程序,顯示一些源代碼。

如果使用C++編碼,使用標準containers應該會有很大的幫助(關於實際的堆棧消耗)。例如,本地(已分配堆棧)std::vector<int> v(10000);(而不是int v[10000];)將其數據分配到堆上(並且在從定義它的塊中退出時由析構函數釋放)

改進程序會好得多以避免過多的堆棧消耗。需要大量的堆棧空間實際上是一個你應該嘗試糾正的錯誤。典型的經驗法則是讓01​​小於幾千字節(因此在堆上分配任何更大的數據)。

你也許還可以考慮使用Boehm conservative garbage collector:你會使用GC_MALLOC代替malloc(你會堆上分配使用GC_MALLOC大數據結構),但你不會費心去free你(GC-堆allcoated)數據。

+0

我編輯了我的問題!我的代碼最重要的是減少計算時間。數組總是保持相同的大小,因此我將它設置爲固定值! – chi86

+0

分配堆中的數組不應該改變CPU的時間。 –

+0

好吧,但我沒有看到優勢,如果我創建它們時將其設置爲固定值。或者是'p(ib:ie,jb:je,kb:ke)'這個問題? – chi86