【发布时间】:2013-05-02 05:27:34
【问题描述】:
我的代码在结构上类似于 Matlab 中的以下代码:
bestConfiguration = 0;
bestConfAwesomeness = 0;
for i=1:X
% note that providing bestConfAwesomeness to the function helps it stop if it sees the current configuration is getting hopeless anyway
[configuration, awesomeness] = expensive_function(i, bestConfAwesomeness);
if awesomeness > bestConfAwesomeness
bestConfAwesomeness = awesomeness;
bestConfiguration = configuration;
end
end
还有更多内容,但基本结构如上。 X 可以非常 大。我试图让这段代码并行运行,因为expensive_function() 需要很长时间才能运行。
问题在于,Matlab 不允许我将 for 更改为 parfor,因为它不喜欢我在循环中更新最佳配置。
到目前为止,我所做的是:
[allConfigurations, allAwesomeness] = deal(cell(1, X));
parfor i=1:X
% note that this is not ideal because I am forced to use 0 as the best awesomeness in all cases
[allConfigurations{i}, allAwesomeness{i}] = expensive_function(i, 0);
end
for i=1:X
configuration = allConfigurations{i};
awesomeness = allAwesomeness{i};
if awesomeness > bestConfAwesomeness
bestConfAwesomeness = awesomeness;
bestConfiguration = configuration;
end
endfor
这在运行时间方面更好;但是,对于大型输入,它会占用大量内存,因为始终保存所有配置。另一个问题是使用parfor 迫使我始终提供0 作为最佳配置,即使可能知道更好的配置。
Matlab 是否提供了更好的方法来做到这一点?
基本上,如果我不必使用 Matlab 并且可以自己管理线程,我会有一个中心线程来为工人提供工作(即让他们运行expensive_function(i)),一旦工人返回,看看它产生的数据并将其与迄今为止发现的最佳数据进行比较并相应地更新它。无需保存所有配置,这似乎是使parfor 工作的唯一方法。
有没有办法在Matlab中做到以上几点?
【问题讨论】:
-
为了能够在调用
expensive_function时使用先验知识,您可以将parfor的范围拆分为更小的扫描(例如,i=1:floor(X/2),然后是i=floor(X/2):X)并使用第一次扫描的最佳结果是播种以下对expensive_function的调用。请注意,此解决方案的可行性取决于对expensive_function的知情调用所节省的运行时间与拥有一个parfor与拥有多个连续parfors 所节省的时间之间的权衡。 -
@H.Muster:我正在考虑这个问题,但这并不理想,因为
expensive_function可能需要很长时间才能进行某些输入,即第一次扫描可能会不必要地等待一小部分当它已经可以从另一部分运行作业时完成它 -
正如我所说,这取决于权衡。作为一种解决方法,
expensive_function可以将其部分结果保存到文件中。然后,在每次调用时,该函数可以检查结果文件是否已经可用,如果是,则利用此先验知识。 -
您的循环迭代不是独立的,因为您使用的是以前迭代的知识(即 bestConfAwesomeness)。这不是一个专门的 MATLAB 问题 - PARFOR 只是在保护您免受竞争条件的影响。
-
@Edric:是的,但不是严格需要 bestConfAwesomeness;它只是为了加快速度,而不是提供它不会改变输出。 IE。如果您一直传递 0,它将给出完全相同的结果,但速度较慢。这是一个 Matlab 问题,因为在大多数其他语言中,您可以执行我在上一段中描述的操作。
标签: multithreading matlab parallel-processing parfor