2011-02-08 83 views
3

我有,我創建了兩個雙維數組像這樣的算法:大型陣列工作 - OutOfRam

TYPE 
    TPtrMatrixLine = array of byte; 
    TCurMatrixLine = array of integer; 
    TPtrMatrix  = array of TPtrMatrixLine;          
    TCurMatrix  = array of TCurMatrixLine; 


    function x 
    var 
    PtrsMX: TPtrMatrix; 
    CurMx : TCurMatrix;   
    begin 
    { Try to allocate RAM } 
    SetLength(PtrsMX, RowNr+1, ColNr+1);        
    SetLength(CurMx , RowNr+1, ColNr+1); 
    for all rows do 
    for all cols do 
    FillMatrixWithData; <------- CPU intensive task. It could take up to 10-20 min 
    end; 

兩個矩陣具有總是相同的尺寸。 矩陣中通常只有2000行和2000列,但有時它可能高達25000x6000,因此對於這兩個矩陣我需要類似146.5 + 586.2 = 732.8MB的RAM。 問題在於,在大多數情況下,這兩個塊需要連續,即使500-600MB的可用RAM在現代計算機上看起來並不多,但我的內存不足。

該算法用基於該單元的鄰居的數據填充該數組的單元。這些操作只是加法和減法。

TCurMatrixLine是一個需要很多或RAM,因爲它使用整數來存儲數據。不幸的是,存儲的值可能有符號,所以我不能使用Word而不是整數。 SmallInt太小(我的值比SmallInt大,但比Word小)。我希望如果有任何其他方式來實現這一點,它不需要增加很多開銷,因爲處理具有這麼多行/列的矩陣已經花費了很多時間。換句話說,我希望減少內存需求不會增加處理時間。

任何想法如何降低內存要求? [I使用Delphi 7]


更新 有人建議,我的陣列的每一行應是一個獨立單維數組。 我根據需要創建了很多行(數組)並將它們存儲在TList中。聽起來很不錯。顯然,不會有問題分配這樣的小內存塊。但我擔心它會對速度產生巨大影響。我現在用

TCurMatrixLine = array of integer;         
TCurMatrix  = array of TCurMatrixLine; 

,因爲它的速度比TCurMatrix= array of array of integer(因爲數據被放置在內存的方式)。因此,以獨立線條打破陣列可能會影響速度。

+1

「SHORT」或「Smallint」是一個有符號的16位整數。這與'WORD`具有相同的尺寸。 – 2011-02-08 13:51:49

+3

矩陣中會有多少個空條目?對於稀疏矩陣(具有默認值的許多條目),列表表示可能更緊湊。 – jpfollenius 2011-02-08 14:01:47

+0

如上所述,SmallInt太小(我的值比SmallInt大,但小於Word)。 – Ampere 2011-02-08 14:39:51

回答

4

使用帶符號2字節整數的建議將極大地幫助您。

另一個有用的策略是通過將{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}添加到.dpr文件中,將您的exe標記爲LARGE_ADDRESS_AWARE。如果您在64位Windows上運行並且將您的地址空間從2GB增加到4GB,這隻會有所幫助。

它可能無法在德爾福7(我似乎記得你正在使用D7),你必須使用FastMM,因爲舊的Borland內存管理器不兼容大地址空間。如果$SetPEFlags不可用,您仍然可以用EDITBIN標記該exe文件。

如果仍然遇到困難,那麼另一個技巧就是分配更小的內存子塊,並使用包裝類將映射索引處理爲適當的子塊和偏移量。您可以使用默認的索引屬性來使調用代碼透明。

當然,這樣的塊分配方法確實會產生一些處理開銷,但如果您在獲取連續塊時遇到麻煩,那麼這是最好的選擇。

2

如果CurMx的元素的絕對值符合單詞,那麼您可以將其存儲在單詞中,並使用另一個布爾數組作爲其符號。它爲每個元素減少1個字節。

1

您是否考慮手動分配堆上的數據結構?
...並測量這將如何影響內存使用情況和性能?

使用堆實際上可能會提高速度並減少內存使用量,因爲可以避免將整個陣列從一個內存段複製到另一個內存段。 (例如,如果你的FillMatrixWithData是用非const開放數組參數聲明的)。