1

我的代码在结构上类似于 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 中完成上述操作?

4

2 回答 2

2

在循环中使用bestConfAwesomeness每次循环意味着循环的迭代不是顺序无关的,因此为什么PARFOR不高兴。您可以采取的一种方法是使用SPMD并让每个工作人员expensiveFunction并行执行,然后与 update 进行通信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
于 2013-05-02T08:40:27.840 回答
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);
于 2013-05-02T05:40:30.867 回答