Main Content

Nestedparforand为了-Loops and Otherparfor要求

Nestedparfor-Loops

You cannot use aparfor-loop inside anotherparfor循环。一个s an example, the following nesting ofparfor-loops is not allowed:

parfor一世= 1:10parforj = 1:5。。。结尾结尾

小费

你不能筑巢parfor直接在另一个parfor循环。一个parfor-loop can call a function that contains aparfor-loop, but you do not get any additional parallelism.

Code Analyzer in the MATLAB®Editor flags the use ofparfor在另一个parfor-环形:

你不能筑巢parfor-loops because parallelization can be performed at only one level. Therefore, choose which loop to run in parallel, and convert the other loop to a为了循环。

Consider the following performance issues when dealing with nested loops:

  • Parallel processing incurs overhead. Generally, you should run the outer loop in parallel, because overhead only occurs once. If you run the inner loop in parallel, then each of the multipleparfor执行会导致开销。看转换嵌套为了-Loops to parfor-Loops为了an example how to measure parallel overhead.

  • Make sure that the number of iterations exceeds the number of workers. Otherwise, you do not use all available workers.

  • 尝试平衡parfor-loop iteration times.parfortries to compensate for some load imbalance.

小费

一个lways run the outermost loop in parallel, because you reduce parallel overhead.

You can also use a function that usesparforand embed it in aparfor循环。Parallelization occurs only at the outer level. In the following example, call a functionMyFun.m一世nside the outerparfor循环。The innerparfor-loop embedded inMyFun.mruns sequentially, not in parallel.

parfori = 1:10 myFun(i)结尾函数MyFun(i)parforj = 1:5。。。结尾结尾

小费

Nestedparfor-loops generally give you no computational benefit.

转换嵌套为了-Loops toparfor-Loops

一个typical use of nested loops is to step through an array using a one-loop variable to index one dimension, and a nested-loop variable to index another dimension. The basic form is:

x =零(n,m);为了a =1:n为了b = 1:m x(a,b)=有趣(a,b)结尾结尾

The following code shows a simple example. Use抽动andTOCto measure the computing time needed.

a = 100;抽动为了i = 1:100为了j= 1:100 a(i,j) = max(abs(eig(rand(A))));结尾结尾TOC
经过的时间为49.376732秒。

You can parallelize either of the nested loops, but you cannot run both in parallel. The reason is that the workers in a parallel pool cannot start or access further parallel pools.

If the loop counted by一世一世s converted to aparfor-loop, then each worker in the pool executes the nested loops using thejloop counter. Thej循环本身不能作为一个parforon each worker.

Because parallel processing incurs overhead, you must choose carefully whether you want to convert either the inner or the outer为了-loop to aparfor循环。The following example shows how to measure the parallel overhead.

第一个仅转换outer为了-loop to aparfor循环。利用抽动andTOCto measure the computing time needed. UseticbytesandTOCBytesto measure how much data is transferred to and from the workers in the parallel pool.

运行新代码,然后再次运行。第一次运行比后续运行慢,因为平行池需要一些时间来启动并使代码可用于工人。

a = 100;抽动ticbytes(gcp);parfori = 1:100为了j= 1:100 a(i,j) = max(abs(eig(rand(A))));结尾结尾TOCBytes(gcp) toc
BytesSentToWorkers BytesReceivedFromWorkers __________________ ________________________ 1 32984 24512 2 33784 25312 3 33784 25312 4 34584 26112 Total 1.3514e+05 1.0125e+05 Elapsed time is 14.130674 seconds.

Next convert only the一世nnerloop to aparfor循环。Measure the time needed and data transferred as in the previous case.

a = 100;抽动ticbytes(gcp);为了i = 1:100parforj= 1:100 a(i,j) = max(abs(eig(rand(A))));结尾结尾TOCBytes(gcp) toc
bytessenttoworkers bytesreceivedfromworkers __________________ __________________________________________________________________________________________________________________________________________________1.3458 6 5.4555+05 2 1.3495 2 1.3496e+06 5.4858e+05 3 1.3496e+05 3 1.3677E+06 5.6034E时间为48.631737秒。

If you convert the一世nnerloop to aparfor- 环,传输的数据的时间和数量都比平行的外循环大得多。在这种情况下,经过的时间几乎与嵌套为了-loop example. The speedup is smaller than running the outer loop in parallel, because you have more data transfer and thus more parallel overhead. Therefore if you execute the一世nner与运行串行相比,并行循环,您没有获得计算好处为了循环。

If you want to reduce parallel overhead and speed up your computation, run the outer loop in parallel.

If you convert the一世nner相反,循环,然后外循环的每次迭代都会启动一个单独的parfor循环。That is, the inner loop conversion creates 100parfor- 环。Each of the multipleparforexecutions incurs overhead. If you want to reduce parallel overhead, you should run the outer loop in parallel instead, because overhead only occurs once.

小费

如果您想加快代码加快代码,请始终并行运行外循环,因为您会减少顶部的平行。

Nested为了-Loops: Requirements and Limitations

If you want to convert a nested为了-loop to aparfor- 环,您必须确保正确分类循环变量,请参阅Troubleshoot Variables in parfor-Loops。If your code does not adhere to the guidelines and restrictions labeled asRequired,您会遇到一个错误。MATLAB在读取代码时捕获其中一些错误。这些错误被标记为Required (static)

Required (static): You must define the range of a为了-loop nested in aparfor-loop by constant numbers or broadcast variables.

In the following example, the code on the left does not work because you define the upper limit of the为了- 通过函数调用环。右侧的代码通过首先定义广播或常数变量来提供解决方法parfor-环形:

Invalid Valid
一个= zeros(100, 200);parfori = 1:大小(a,1)为了j= 1:size(A, 2) A(i, j) = i + j;结尾结尾
一个= zeros(100, 200); n = size(A, 2);parfori = 1:大小(a,1)为了j = 1:n a(i,j)= i + j;结尾结尾
Required (static): The index variable for the nested为了- 除了它的为了陈述。

遵循此限制。如果筑巢为了-loop变量在任何地方更改parfor-loop other than by its为了声明,该地区由为了-loop variable is not guaranteed to be available at each worker.

左侧的代码无效,因为它试图修改嵌套的值为了-loop variablej在循环的身体中。右侧的代码通过分配嵌套来提供解决方法为了-loop variable to a temporary variablet,,,,and then updatingt

Invalid Valid
一个= zeros(10);parfor一世= 1:10为了j= 1:10 A(i, j) = 1; j = j+1;结尾结尾
一个= zeros(10);parfor一世= 1:10为了j= 1:10 A(i, j) = 1; t = j; t = t + 1;结尾结尾
Required (static):您不能索引或下标嵌套为了-loop variable.

遵循此限制。如果是嵌套为了- 环变量是索引的,迭代不保证是独立的。

左侧的示例无效,因为它试图索引嵌套为了-loop variablej。The example on the right removes this indexing.

Invalid Valid
一个= zeros(10);parfor一世= 1:10为了j = 1:10 j(1);结尾结尾
一个= zeros(10);parfor一世= 1:10为了j= 1:10 j;结尾结尾
Required (static): When using the nested为了-loop variable for indexing a sliced array, you must use the variable in plain form, not as part of an expression.

For example, the following code on the left does not work, but the code on the right does:

Invalid Valid
一个= zeros(4, 11);parfor一世= 1:4为了j = 1:10 a(i,j + 1)= i + j;结尾结尾
一个= zeros(4, 11);parfor一世= 1:4为了j= 2:11 A(i, j) = i + j - 1;结尾结尾
Required (static): If you use a nested为了-loop to index into a sliced array, you cannot use that array elsewhere in theparfor循环。

In the following example, the code on the left does not work because一个一世s sliced and indexed inside the nested为了循环。The code on the right works becausev一世s assigned to一个outside of the nested loop:

Invalid Valid
一个= zeros(4, 10);parfor一世= 1:4为了j = 1:10 a(i,j)= i + j;结尾disp(A(i, j))结尾
一个= zeros(4, 10);parfor一世= 1:4 v = zeros(1, 10);为了j = 1:10 v (j) = + j;结尾disp(v(j))a(i,:) = v;结尾

parfor-Loop Limitations

嵌套功能

The body of aparfor-loop cannot reference a nested function. However, it can call a nested function by a function handle. Try the following example. Note thata(idx)= nfcn(idx)一世n theparfor- 环不起作用。您必须使用feval调用fcnhandle in theparfor-loop body.

函数a = pfeg函数out = nfcn(in) out = 1 + in;结尾fcn = @nfcn;parfor一世dx = 1:10 A(idx) = feval(fcn, idx);结尾结尾
>> PFEG使用“本地”配置文件...连接到4名工人。ans = 2 3 4 5 6 7 8 9 10 11

小费

如果使用函数句柄,指的是指嵌套功能parfor-loop, then the values of externally scoped variables are not synchronized among the workers.

Nestedparfor-Loops

The body of aparfor-loop cannot contain aparfor循环。有关更多信息,请参阅Nested parfor-Loops

NestedSPMD语句

The body of aparfor- 环不能包含SPMD声明和一个SPMD语句不能包含一个parfor循环。原因是workers cannot start or access further parallel pools.

休息and返回语句

The body of aparfor-loop cannot contain休息or返回statements. Consider帕菲瓦尔or帕菲瓦尔OnAll相反,因为您可以使用取消on them.

Global and Persistent Variables

The body of aparfor-loop cannot containglobalor执着的可变声明。原因是这些变量在工人之间不同步。您可以使用globalor执着的函数中的变量,但是它们的价值仅对创建它们的工人可见。代替globalvariables, it is a better practice to use function arguments to share values.

To learn more about variable requirements, seeTroubleshoot Variables in parfor-Loops

Scripts

If a script introduces a variable, you cannot call this script from within aparfor-loop orSPMD陈述。原因是该脚本会导致透明度违反。有关更多详细信息,请参阅确保Parfor-Loops或SPMD语句的透明度

匿名函数

您可以在体内定义一个匿名功能parfor循环。但是,不支持匿名函数内的切片输出变量。金宝app您可以通过对切片变量使用临时变量来解决此问题,如下所示。

x = 1:10;parfor我= 1:10 temp = x(i); anonymousFunction = @() 2*temp; x(i) = anonymousFunction() + i;结尾disp(x);

有关切片变量的更多信息,请参阅Sliced Variables

输入名功能

使用输入名to return the workspace variable name corresponding to an argument number is not supported insideparfor- 环。原因是parfor工人无法访问MATLAB桌面的工作空间。要解决这个问题,请致电输入名beforeparfor,,,,as shown in the following example.

a ='a'; myFunction(a)函数X = myFunction(a) name = inputname(1);parfor一世=1:2 X(i).(name) = i;结尾结尾

加载功能

The syntaxes of加载在内部不支持未分配给输出结构的金宝appparfor- 环。Insideparfor,始终分配输出加载to a structure.

narginornargout功能

The following uses are not supported insideparfor- 环:

  • 使用narginornargoutwithout a function argument

  • 使用narginchkornargoutchkto validate the number of input or output arguments in a call to the function that is currently executing

原因是工人无法访问MATLAB桌面的工作空间。要解决这个问题,请致电these functions beforeparfor,,,,as shown in the following example.

myfunction('a',,,,'b'函数X = myFunction(a,b) nin = nargin;parfor一世=1:2 X(i) = i*nin;结尾结尾

P-Code Scripts

您可以从一个内部调用p代码脚本文件parfor- 环,但是p代码脚本不能包含一个parfor循环。为了解决这一问题,使用p代码函数一世nstead of a P-code script.

也可以看看

||

Related Topics