0

我在 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非常大,保存所有数据输出将非常占用内存。

还有另一种方法吗?

4

2 回答 2

1

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

然后将结果存储在一个仍由循环索引切片的临时变量中,然后将它们组合在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循环中应用掩码之前执行相反的操作。根据您的面具的结构,这可能会节省额外的空间。

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

于 2013-05-02T03:30:37.760 回答
-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
于 2013-05-02T03:36:22.330 回答