我的代码在结构上类似于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中执行上述操作?
答案 0 :(得分:2)
每次循环使用bestConfAwesomeness
意味着循环的迭代不是与顺序无关的,因此PARFOR
不满意的原因。您可以采用的一种方法是使用SPMD
并让每个工作人员并行执行expensiveFunction
,然后进行通信以更新bestConfAwesomeness
。像这样:
bestConfiguration = 0;
bestConfAwesomeness = 0;
spmd
for idx = 1:ceil(X/numlabs)
myIdx = labindex + ((idx-1) * numlabs);
% should really guard against myIdx > X here.
[thisConf, thisAwesome] = expensiveFunction(myIdx, bestConfAwesomeness);
% Now, we must communicate to see if who is best
[bestConfiguration, bestAwesomeness] = reduceAwesomeness(...
bestConfiguration, bestConfAwesomeness, thisConf, thisAwesome);
end
end
function [bestConf, bestConfAwesome] = reduceAwesomeness(...
bestConf, bestConfAwesome, thisConf, thisAwesome)
% slightly lazy way of doing this, could be optimized
% but probably not worth it if conf & awesome both scalars.
allConfs = gcat(bestConf);
allAwesome = gcat(thisAwesome);
[maxThisTime, maxLoc] = max(allAwesome);
if maxThisTime > bestConfAwesome
bestConfAwesome = maxThisTime;
bestConf = allConfs(maxLoc);
end
end
答案 1 :(得分:1)
我不确定使用Matlab可以控制你的线程。但是,由于X
非常大,因此可能值得执行以下操作,这会使您再花费expensiveFunction
次迭代:
%# calculate awesomeness
parfor i=1:X
[~,awesomeness(i)] = expensiveFunction(i);
end
%# find the most awesome i
[mostAwesome,mostAwesomeIdx] = min(awesomeness);
%# get the corresponding configuration
bestConfiguration = expensiveFunction(mostAwesomeIdx);