Matlab - 如何转换此代码以便它可以使用parfor运行?

时间:2013-05-02 03:11:09

标签: matlab parallel-processing parfor

我在Matlab中有以下代码(当然是简化的,但这显示了问题的根源),之前使用过for;我想将其更改为使用parfor代替:

isForeground = ones(1, size(In, 1));

% this used to be a simple for
parfor i=1:X
   data = output_of_some_expensive_function();

   % do some other stuff with data here

   % the part below is the problem; isForeground basically keeps track of all the places where data was never a zero
   isForeground(data == 0) = 0; 
end

Matlab抱怨说Valid indices for 'isForeground' are restricted in PARFOR loops。有办法解决这个问题吗?我想过只保存所有data输出,然后运行一个单独的传统for循环,我将执行isForeground部分,但问题是X非常大而且保存所有数据输出将是非常耗费内存的。

还有另一种方法吗?

2 个答案:

答案 0 :(得分:1)

结果中1的密度是多少?如果它们是稀疏的(即大部分为0),find()可以将逻辑掩码缩小到数字索引列表。如果您需要进一步压缩,根据X的大小,您可以将存储的掩码转换为uint32uint16,这将占用double空间的1/2或1/4

然后将结果存储在仍然由循环索引切片的临时变量中,然后将它们组合在parfor循环之外,就像你说的那样。

masks = cell(1, X);
parfor i=1:X
   data = output_of_some_expensive_function();

   % do some other stuff with data here

   % stash the loop results in a non-combining manner
   masks{i} = uint32(find(data == 0));
end

% Combine in regular for loop

for i=1:X
   isForeground(double(masks{i})) = 0; 
end

如果这还不够,也许您可​​以将每个结果掩码写入常见的驱动器空间或其他持久对象存储上的.mat文件中的磁盘。如果parfor的工作人员在本地计算机上,则任何驱动器都可以正常工作,并且应该很快,因为您可能只是通过操作系统的磁盘缓存。

您还可以尝试将输出掩码转换为可压缩格式。例如。在其上运行diff()并将结果压缩到byte[]“blob”,然后在常规for循环中应用掩码之前执行反向右移。根据面具的结构,这可能会节省更多空间。

注意:逻辑占用的存储空间比您想象的要多;即使每个元素只有一位有意义的信息,它需要一整个字节的内存,因为这是最小的可寻址内存单元。

答案 1 :(得分:-1)

此代码现在使用struct从parfor传递数据:

In = eye(3); % some input
X = size(In, 1);

isForeground = ones(1, X);
isForeground_struct = repmat(struct('data', ones(1, X)), [1, X]);

% is used to be a simple for
parfor i=1:X
   data = ones(1, X);
   data(randi(X)) = 0; % a random operator just to make an example for data

   isForeground_struct(i).data = data; 
end

isForeground = prod(cat(1, isForeground_struct.data)); % assuming you want AND combination