内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.
我究竟做错了什么?
从文档上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
从一开始就循环。 也就是说,像这样的错误不会花费你在你的转码功能,每天的唯一途径。
从转换for
以parfor
一点也不平凡 。
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