仅通过矩阵转置内存不足

时间:2014-10-19 17:44:24

标签: database matlab database-design signal-processing octave

我有一个单元格Data,它包含三个 double 数组,

 Data = 

[74003x253 double]    [8061x253 double]    [7241x253 double]

我正在使用循环来读取这些数组并执行一些函数,

for ii = 1 : 3
    D = Data {ii} ;
    m = mean (D') ;
    // rest of the code
end

mean发出警告并说:

考虑为MEAN使用不同的DIMENSION输入参数

但是,当我将其更改为时,

for ii = 1 : 3
    D = Data {ii}' ;
    m = mean (D) ;
    // rest of the code
end

我得到内存不足错误

比较两个代码,有人可以解释会发生什么吗?

似乎我只用复共轭转置得到了错误(我的数据是实值)。

3 个答案:

答案 0 :(得分:8)

要取n:th维度的均值,可以使用mean(D,n),如前所述。关于内存消耗,我用windows资源管理器进行了一些测试监控。产量有点预期。

当执行操作D=Data{ii}时,只消耗最小内存,因为这里matlab只是复制指针。但是,在进行转置时,matlab需要分配更多的内存来存储矩阵D,这意味着内存消耗会增加。

然而,这仅仅不会导致内存溢出,因为在两种情况下都进行了转置。

案例1

分别在D = Data{ii}';

案例2

D = Data {ii}; m = mean(D');

不同之处在于,在案例2 中,matlab仅创建Data{ii}'的临时副本,该副本未存储在工作区中。分配的内存在两种情况下都相同,但案例1 Data{ii}'存储在D中。当内存稍后增加时,这可能导致内存溢出。

D的内存消耗并不差(<200 Mb),但猜测是内存已经很高并且这足以让内存溢出。

答案 1 :(得分:6)

警告信息表示代替,

m = mean (D') ;

你应该这样做:

m = mean (D,2);

这将采用第二维的平均值,为您留下长度为size(D,1)的列向量。

我不知道为什么在执行D = Data {ii}'时只会出现内存不足错误。也许是因为当你将它放在mean的一边时(m = mean (D') ;,JIT设法以某种方式进行优化并节省你浪费的记忆。

答案 2 :(得分:1)

以下是执行此操作的一些方法:

for i = 1 : length(Data)
   % as chappjc recommends this is an excellent solution
   m = mean(Data{i}, 2);
end

或者,如果您想要转置,并且您知道数据是真实的(不复杂)

for i = 1 : length(Data)
   m = mean(Data{i}.');
end

注意,转置前的点。

或者,一起跳过循环

m = cellfun(@(d) mean(d, 2), Data, 'uniformoutput', false);

当你这样做时:

D = Data{i}'

Matlab将创建数据的新副本。这将分配74003x253双打,大约150MB。正如帕特里克指出的那样,假设您可能有其他数据,则很容易超出允许的内存分配使用量(特别是在32位计算机上)。

如果您遇到内存问题,计算不敏感,您可以考虑使用单精度而不是双精度,即:

data{i} = single(data{i});

理想情况下,您希望在分配点执行单精度,以避免不必要的新分配和复制。

祝你好运。