【问题标题】:Matlab Parfor loop not workingMatlab Parfor循环不起作用
【发布时间】:2015-11-22 03:22:49
【问题描述】:

我正在使用fminsearch 将模型拟合到多个数据集,并且我正在尝试并行执行它们。我的代码一直运行到parfor 循环的开始,但是parfor 循环似乎需要永远 才能开始! (parfor 中的第一行没有被执行)。没有错误,matlab 只是保持“忙碌”。

我在具有 4 个内核的本地集群上运行,以 matlabpool 4 开头,它似乎可以正常启动。我在 Ubuntu 14.04.3 上运行 Matlab R2014b 64 位,八核 i7-3770K @ 3.50GHz,24GiB RAM(当然大部分没有使用)。

编辑

这是重现问题的代码!

文件matlab_parfor_test_2

function f=matlab_parfor_test_2
f={}; 
for i=1:400
  a=@(p)i*p;             % make some functions depending on i
  b=@(p)a(p)+0;          % a function depending on this
  f=[f { @(p)b(p) }];    % create a list of i functions using this
end

文件matlab_parfor_test_1

function matlab_parfor_test_1
f=matlab_parfor_test_2(); % create the functions
f=f(1:2);       % discard all but two functions
for i=1:2       % for each function                ('A')
  parfor j=1    % dummy parfor 
    tmp=f{i}; % just read a function from the cell ('B')
  end
end

在我的机器上从“A”到第一个“B”所用的时间(即“输入”parfor 所用的时间)是

returning 400 functions: 20 sec
          500 functions: 32 sec
          600 functions: 45 sec
          700 functions: 64 sec

这很奇怪,因为在test_1 中,我丢弃了除 2 个以外的所有功能!为什么丢弃的功能会导致速度变慢?

我想也许 matlab 实际上并没有删除 f 中不需要的函数。所以我尝试用

替换f=f(1:2)
f={f{1}, f{2}}; 

但这也无济于事。

如果我将parfor 替换为for,那么执行当然需要不到1ms。

有什么想法吗??

旧版问题

function fit_all
  models = createModelFunctions();  % creates cell of function handles
  data   = { [1 2 3], [1 2 3] };    % create 2 data sets
  for i = 1:length(models)
    fprintf('model %g\n',i);
    parfor j = 1:length(data)
      fprintf('data %g\n',j);
      tmp = models{i};  % if I comment this line out, it runs fine!
      % p(j) = fminsearch(@(p)models{j}(p,data{j}), [0 0]);
    end
  end

模型函数在另一个文件中创建,

function models = createModelFunctions()
  models{1} = @(p,d) likelihoodfun(0,0,p,d);
  models{2} = @(p,d) likelihoodfun(1,0,p,d); 

function L = likelihoodfun(a,b,p,d)
  L = some maths here;

运行fit_all,我希望看到model 1data 1data 2model 2 等列表。我得到的输出是

model 1

然后事情就停止了:没有提示,matlab 说“忙”,UI 和操作系统照常响应。系统监视器显示只有 1 个内核处于活动状态。它永远不会进入parfor。 如果我此时按ctrl+C,则在延迟 3 分钟后,我会得到

Operation terminated by user during parallel.internal.pool.serialize (line 21)
In distcomp.remoteparfor (line 69)
                serializedInitData = parallel.internal.pool.serialize(varargin);
In parallel_function>iMakeRemoteParfor (line 1060)
P = distcomp.remoteparfor(pool, W, @make_channel, parfor_C);
In parallel_function (line 444)
        [P, W] = iMakeRemoteParfor(pool, W, parfor_C);

如果我注释掉指示的行,它可以工作——所以问题似乎出在我访问模型函数时......同样,如果我将模型更改为

 models={@sum,@sum}

即只是当我使用另一个文件中的函数句柄时......

【问题讨论】:

  • 我在 Windows 上运行 Matlab 2014a 64 位,我无法重现您的问题(它工作正常)。我会尝试两件事:(1)将 parfor 放在外循环中。 (2) 尝试在没有单元格数组的情况下实现它。 (2) 更像是在黑暗中拍摄,但我过去在使用 struct array 和 parfor 时遇到过问题,所以也许......
  • 嗯,你是对的。它必须与函数本身有关。如果我用一个非常简单的外部函数替换它,就没有问题了。我会做实验。
  • 我的意思是我用你的函数试了一下(只是设置L=0),效果很好。
  • 我运行了一些新的测试!结果出乎意料。问题已编辑。谢谢

标签: matlab parfor


【解决方案1】:

当我在我的机器上运行您的代码时,它运行良好。在我的 Windows 和 Linux 上。但是,第一次运行总是需要更长的时间,因为您必须打开一个并行池,您指的是这个吗?如果是这样,这是正常的预期行为。

仅供参考,您应该使用 parpool 而不是 matlabpool。也许过时的 matlabpool 代码在创建池时遇到问题?另外,请确保它不会每次都关闭您的并行池。

如果这些都不起作用,请在其他人的计算机上尝试该代码,看看是否可以重现问题。

【讨论】:

    猜你喜欢
    • 2012-07-22
    • 1970-01-01
    • 2014-06-10
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多