如何在matlab中预先分配外部数据结构列表?

时间:2014-11-19 16:50:43

标签: matlab

我的问题与外部定义的数据结构:tensor有关。 Tensor是一个多维数组。在Matlab tensor toolbox 2.5中,tensor是一个包含两个字段的类:t.data,t.size:

   % Create the tensor
    t.data = data;
    t.size = siz;
    t = class(t, 'tensor');
    return;

与Matlab中的内置函数zeros()一样,我可以使用tenzeros()来创建一个充满零的张量,例如,tenzeros([2,3,4])。此工具箱中还有其他类型的张量数据结构:张量,sptensor,ktensor,ttensor等。

我的问题是,如何预分配200个tenzeros或其他张量类型,其中每个张量的大小相同[100,200,300]?也就是说,为200个张量预分配内存。原因是我目前使用for循环逐个创建200个张量,内存要求非常高。有些人建议我在我真正计算之前为大数据结构预分配内存。

因此,我想在开始时预先分配200个张量的数组;然后在 for循环(特别是 parfor循环)中,我计算每个张量的实际结果并将其发送到预分配的空间。

为什么我无法使用:

 c=repmat(tenzeros([100, 200, 300]),200,1)

抛出:

Error using tensor.size
Too many output arguments.

Error in repmat (line 73)
    [m,n] = size(A);

----------


更新

我预先为200个张量分配内存,因为我听说内存预分配可以使数据在内存中连续,从而可以缓解OutOfMemory问题。实际上我只需要在for循环中将每个计算张量写入每个txt文件中,这意味着我不需要将200个张量一起作为我的最终结果。

所以目前我正在使用@Andrew Janke的第三段代码在开始时为200个张量预先分配内存:

%Memory pre-allocation
c = cell([200, 1]);
parfor i = 1:numel(c)
    c{i} = tenrand([100,200,300]); %This is just a tensor with random values to fill in the memory space
end

然后我在parfor循环中虚拟计算200个张量并填充预先分配的内存空间(即c):

%Compute the 200 tensors in a parfor loop
parfor i = 1: 200
c{i} = computeTensorFunction(...)...;
aTensor = c{i};
write aTensor (i.e. c{i}) into a text file...;
end
  • 第二部分是否会用预先分配的内存覆盖c中的空格?
  • 表现aTensor = c{i}:它没有复制副本,对吗? (我不对aTensor进行更改)

1 个答案:

答案 0 :(得分:0)

您可以使用tensor基本上按照您的方式预先分配已初始化的repmat对象的单元格数组,但是将每个张量都固定在单元格内。

c=repmat( { tenzeros([100, 200, 300]) }, 200, 1);

围绕{ }调用的tenzeros花括号将其括在1 x 1单元格中。

如果repmat正在爆炸,您可以通过自己从重复使用的临时变量中分配单元格内容来解决它。这基本上与repmat一样快,并具有相同的内存使用特性。

sz = [200, 1];
c = cell(sz);
% Construct initial value *once* outside the loop
tmp = tensor(...);
for i = 1:numel(c)
    c{i} = tmp;
end    

请注意,这不会像预分配原始数组那样对性能起作用,因为只有复合类型的顶级“容器”级别才会被预先分配并可能就地修改。存储在对象(如张量)字段中的数组在函数内部更改其值时仍会被复制,甚至可能在首次创建它们的本地工作空间中复制。

这将有助于峰值内存使用量,因为所有初始零张量将通过写时复制优化共享其内存。因此,在多个构造函数调用的循环中使用新的张量初始化单元数组更有效。但是,既然你要丢弃那些初始的零值,那么最有效的方法就是用空单元初始化它。

sz = [200, 1];
c = cell(sz);
parfor i = 1:numel(c)
    c{i} = calculate_your_result(...);
end

因为tensor是复合类型(对象),所以预分配对它们消耗的空间没有多大帮助。您应该在最佳情况下计算出数据集需要多少内存,并查看与您所看到的实际使用情况的对比情况。您可能只需要更多内存用于此应用程序。