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列,但有时它可以高达25000×6000,因此对于两个矩阵我需要146.5 586.2 = 732.8MB的RAM.
问题是这两个块需要连续,所以在大多数情况下,即使现代计算机上的500-600MB空闲RAM看起来不多,我也会耗尽RAM.
该算法使用基于该单元的邻居的数据填充阵列的单元.操作只是加法和减法.
TCurMatrixLine是一个需要很多或RAM的,因为它使用整数来存储数据.不幸的是,存储的值可能有符号,所以我不能使用Word而不是整数. SmallInt太小(我的值比SmallInt大,但比Word小).我希望如果有任何其他方法来实现它,它不需要增加很多开销,因为处理具有如此多行/列的矩阵已经花费了大量时间.换句话说,我希望降低内存需求不会增加处理时间.
知道如何降低内存要求吗?
[我使用Delphi 7]
更新
有人建议我的数组的每一行都应该是一个独立的单维数组.
我根据需要创建了很多行(数组)并将它们存储在TList中.听起来很不错.显然,分配这么小的内存块没有问题.但我担心它会对速度产生巨大影响.我现在用
TCurMatrixLine = array of integer; TCurMatrix = array of TCurMatrixLine;
因为它比TCurMatrix =整数数组的数组快(因为数据放在内存中的方式).因此,在独立行中断开阵列可能会影响速度.
使用带符号的2字节整数的建议将极大地帮助您.另一个有用的策略是通过将{$SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE}添加到.dpr文件来将您的exe标记为LARGE_ADDRESS_AWARE.这只有在64位Windows上运行时才有用,并且会将地址空间从2GB增加到4GB.
它可能不适用于Delphi 7(我似乎记得你使用的是D7)并且你必须使用FastMM,因为旧的Borland内存管理器与大地址空间不兼容.如果$SetPEFlags不可用,您仍然可以使用EDITBIN标记exe.
如果您仍然遇到困难,那么另一个技巧是分配较小的内存子块并使用包装类来处理映射索引到适当的子块并在其中进行偏移.您可以使用默认索引属性使其对调用代码透明.
当然,像这样的块分配方法确实会产生一些处理开销,但如果你遇到连续块的麻烦,这是你最好的选择.