2011-02-08 45 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开放数组参数声明的)。