全局和PARFOR(globals and parfor)

2019-06-27 13:48发布

parfor循环,我想调用访问功能global无济于事。

功能

function a = getA()
   global OPTIONS;
   a=OPTIONS.PROBLEM.A;
end

循环:

parfor i=1:3
    b=getA();
end

错误:

Error using parallel_function (line 589)

Attempt to reference field of non-structure array.

我究竟做错了什么?

Answer 1:

从文档上parfor

一个PARFOR循环的身体无法遏制全球性或持续性变量声明。

在你的问题,即背景下,调用中的一个函数parfor ,反过来引用global而言,这意味着:“ parfor可能不会给期望的或有意义的结果”。

这非常有意义。 考虑以下

Lab 1:         Lab 2: 

GetB();        GetB();

如果内容GetB()是这样的:

function GetB()
    global B;

    %# do something useful

    B = rand;

 end

会的价值是什么B当上引用的是Lab 1 ? 和Lab 2 ? 的不同结果是如何rand沟通? 这将是一个烂摊子!

编写适合代码parfor循环可以是一个真正的痛苦时代码来自东西,只有正常for记-loops。 一般来说,当你事先知道你要编写一个计算密集型一段Matlab代码,编写所有功能和循环为parfor从一开始就循环。 也就是说,像这样的错误不会花费你在你的转码功能,每天的唯一途径。

从转换forparfor 一点也不平凡



Answer 2:

GLOBAL数据很难使用里面PARFOR ,因为每个工人是一个单独的MATLAB程序,和全局变量不会从客户端(或任何其他处理)至工人同步。 如果从对工人一个单独的函数初始化的全局数据会工作。 (正如罗迪所指出的,使用global 直接关键字在一个PARFOR循环体内是不允许的-然而,单独的函数可以做到这一点)。 因此,这将是法律要做到这一点:

parfor ii=1:matlabpool('size')
  myFcnWhichSetsUpGlobalData(); %# defines global OPTIONS
end
parfor ii=1:N
  result(ii) = myFcnWhichUsesGlobalData(); %# reads global OPTIONS
end

我会亲自尝试删除GLOBAL从应用程序中的数据-这将使它更好的工作PARFOR ,并且它将使依赖更加清晰。

一个进一步的选项来探讨的是我的工人对象封装 ,其目的是阻止你不必将数据传送到工人多次。 你可能会使用这种方式:

options = buildOptions();
w_options = WorkerObjWrapper(options);
parfor ii=1:N
  result(ii) = myFcnNeedingOptions(ii, w_options.Value);
end


文章来源: globals and parfor