主要内容

嵌套的parfor循环和其他parfor需求

嵌套的parfor循环

你不能使用parfor循环在另一个parfor循环。作为一个例子,下面的嵌套parfor循环是不允许的:

parfori = 1:10parforj = 1:5结束结束

提示

你不能嵌套parfor直接在另一个parfor循环。一个parfor循环可以调用一个函数,其中包含一个parfor循环,但你不会得到任何额外的并行性。

在MATLAB代码分析器®编辑器标记的使用parfor在另一个parfor循环:

你不能嵌套parfor循环,因为并行可以执行在只有一个水平。因此,选择要并行运行的循环,把另一个循环循环。

考虑以下性能问题在处理嵌套循环:

  • 并行处理会增加开销。一般来说,你应该外循环并行运行,因为开销只发生一次。如果你并行运行内部循环,那么每个多个parfor死刑带来的开销。看到转换parfor-Loops嵌套的for循环例如如何衡量并行开销。

  • 确保迭代次数超过工人的数量。否则,你不使用所有可用的工人。

  • 试着去平衡parfor循环迭代时间。parfor试图弥补一些负载不平衡。

提示

总是最外层循环并行运行,因为你减少并行开销。

您还可以使用一个函数,使用parfor并将它嵌入parfor循环。并行化只发生在外层的水平。在下列的示例中,调用一个函数MyFun.m在外面parfor循环。内parfor循环嵌入MyFun.m按顺序运行,而不是平行的。

parfor我= 1:10 MyFun(我)结束函数MyFun(我)parforj = 1:5结束结束

提示

嵌套的parfor循环通常给你计算没有好处。

将嵌套循环,parfor循环

典型的使用嵌套循环使用一个循环遍历一个数组变量指数一维,和一个内嵌循环变量指数另一个维度。基本形式是:

X = 0 (n, m);一个= 1:nb = 1: m X (a, b) =乐趣(a, b)结束结束

下面的代码显示了一个简单的例子。使用抽搐toc测量所需的计算时间。

一个= 100;抽搐i = 1:10 0j = 1:10 0 (i, j) = max (abs (eig(兰德(a))));结束结束toc
运行时间是49.376732秒。

您可以嵌套循环的并行化,但你不能并行运行。原因是,工人们在一个平行池不能启动或访问进一步平行池。

如果循环数转换为parfor池中循环,然后每个工人执行嵌套循环使用j循环计数器。的j循环本身不能运行parfor在每一个工人。

因为并行处理会增加开销,你必须仔细选择你是否想把内部或外部循环,parfor循环。下面的例子展示了如何衡量并行开销。

首先将只循环,parfor循环。使用抽搐toc测量所需的计算时间。使用ticBytestocBytes测量多少数据转移的工人在并行池。

运行新代码,并再次运行它。第一次运行比后续运行慢,因为平行池需要一些时间开始,使可用的代码工人。

一个= 100;抽搐ticBytes (gcp);parfori = 1:10 0j = 1:10 0 (i, j) = max (abs (eig(兰德(a))));结束结束tocBytes toc (gcp)
BytesSentToWorkers BytesReceivedFromWorkers _____________ ________________________ 1 32984 24512 33784 25312 3 33784 25312 4 34584 26112 1.3514 1.0125 e + e + 05年05年运行时间是14.130674秒。

下一只转换内心的循环parfor循环。测量所需的时间和数据传输与前面的情况。

一个= 100;抽搐ticBytes (gcp);i = 1:10 0parforj = 1:10 0 (i, j) = max (abs (eig(兰德(a))));结束结束tocBytes toc (gcp)
BytesSentToWorkers BytesReceivedFromWorkers _____________ ________________________ 1 1.3496 1.3496 5.487 e + e + 06 05年2 5.4858 e + e + 06 05年3 1.3476 1.3677 5.6034 e + e + 06 05年4 e + 06 5.4717总5.4144 e + e + 05 06 2.2048 e + 06年运行时间是48.631737秒。

如果你把内心的循环parfor循环,时间和传输的数据量远远大于在平行的外循环。在这种情况下,运行时间几乎是一样的嵌套循环的例子。运行的速度小于外循环并行,因为你有更多的数据传输,因此并行开销。因此如果你执行内心的并行循环,得到比运行串行计算没有好处循环。

如果你想减少并行开销和加速你的计算,并行运行外循环。

如果你把内心的外循环的每次迭代循环,然后启动一个单独的parfor循环。内循环转换创建100年parfor循环。每一个多个parfor死刑会增加开销。如果你想减少并行开销,你应该并行运行外循环,因为开销只发生一次。

提示

如果你想加快代码,总是外循环并行运行,因为你减少并行开销。

嵌套的循环:需求和局限性

如果你想转换一个嵌套循环,parfor循环,您必须确保您的循环变量分类是适当的,看到的排除变量parfor-Loops。如果您的代码不遵守指导方针和限制贴上要求,你会得到一个错误。MATLAB捕获其中的一些错误时它读取代码。这些错误都贴上要求(静态)

要求(静态):你必须定义的范围循环嵌套在一个parfor循环常数或广播变量。

在接下来的例子中,左边的代码不工作因为你定义的上限由一个函数调用循环。右边的代码提供了一个解决方法首先定义一个广播或常量变量之外的parfor循环:

无效的 有效的
一个= 0 (100、200);parfori = 1:尺寸(1)j = 1:尺寸(2)(i, j) =我+ j;结束结束
一个= 0 (100、200);n =大小(2);parfori = 1:尺寸(1)j = 1: n (i, j) =我+ j;结束结束
要求(静态):索引变量嵌套循环绝对不能显式地指定的声明。

下面这个限制是必需的。如果嵌套循环变量是改变了在一个地方parfor循环的声明中,索引的循环变量是不能保证可以在每个工人。

左边的代码是无效的,因为它试图修改嵌套的价值循环变量j在体内的循环。右边的代码提供了一个通过指定嵌套解决方案循环变量来一个临时变量t,然后更新t

无效的 有效的
一个= 0 (10);parfori = 1:10j = 1:10 (i, j) = 1;j = + 1;结束结束
一个= 0 (10);parfori = 1:10j = 1:10 (i, j) = 1;t = j;t = t + 1;结束结束
要求(静态):你不能索引或下标嵌套循环变量。

下面这个限制是必需的。如果一个嵌套的循环变量索引、迭代不能保证独立。

左边的例子是无效的,因为它试图指数嵌套循环变量j。右边的例子会删除这个索引。

无效的 有效的
一个= 0 (10);parfori = 1:10j = 1:10 j (1);结束结束
一个= 0 (10);parfori = 1:10j = 1:10;结束结束
要求(静态):当使用嵌套循环变量数组索引一个切片,您必须使用普通形式的变量,而不是作为一个表达式的一部分。

例如,下面的代码左边不工作,但是右边的代码:

无效的 有效的
一个= 0 (11);parfori = 1:4j = 1:10 (i, j + 1) = i + j;结束结束
一个= 0 (11);parfori = 1:4j = 2:11 (i, j) =我+ j - 1;结束结束
要求(静态):如果你使用一个嵌套循环索引到切片数组,你不能使用其他地方的数组parfor循环。

在接下来的例子中,因为左边的代码不工作一个嵌套的内切和索引吗循环。右边的代码,因为工作v被分配给一个外的嵌套循环:

无效的 有效的
A = 0 (10);parfori = 1:4j = 1:10 (i, j) = i + j;结束disp ((i, j))结束
A = 0 (10);parfor我= 1:4 v = 0 (10);j = 1:10 v (j) = + j;结束disp (v (j))(我:)= v;结束

parfor循环的限制

嵌套函数

的身体parfor循环嵌套函数不能引用。然而,它可以由一个函数调用一个嵌套函数处理。尝试下面的例子。请注意,(idx) = nfcn (idx)parfor循环不工作。你必须使用函数宏指令来调用fcn处理的parfor循环体。

函数一个= pfeg函数= nfcn(在)= 1 +;结束fcn = @nfcn;parforidx = 1:10 (idx) =函数宏指令(fcn idx);结束结束
> > pfeg开始平行池(parpool)使用“本地”概要文件…连接到4工人。ans = 2 3 4 5 6 7 8 9 10 11

提示

如果你使用函数处理指的是在一个嵌套的函数parfor循环,那么外部作用域的变量的值不同步的工人。

嵌套的parfor循环

的身体parfor循环不能包含一个parfor循环。有关更多信息,请参见嵌套parfor-Loops

嵌套的spmd语句

的身体parfor循环不能包含一个spmd声明中,和一个spmd语句不能包含一个parfor循环。原因是工人不能启动或访问进一步平行池。

打破返回语句

的身体parfor循环不能包含打破返回语句。考虑parfevalparfevalOnAll相反,因为您可以使用取消在他们身上。

全球和持久的变量

的身体parfor循环不能包含全球持续的变量声明。原因是这些变量之间的不同步的工人。您可以使用全球持续的函数内的变量,但他们的价值仅是可见的工人创造了他们。而不是全球变量,它是一个更好的实践使用函数参数共享价值观。

了解更多关于变量要求,明白了排除变量parfor-Loops

脚本

如果一个脚本引入了一个变量,你不能从在调用这个脚本parfor循环或spmd声明。原因是这个脚本会导致违反透明度。更多细节,请参阅确保parfor-Loops或spmd语句的透明度

匿名函数

您可以定义一个匿名函数体内parfor循环。但是,切片输出变量内部不支持匿名函数。金宝app你可以使用一个临时变量来解决这个切片的变量,如以下示例所示。

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

切变量的更多信息,请参阅切变量

inputname功能

使用inputname返回工作空间变量名称对应于一个参数数量不支持金宝appparfor循环。原因在于,parfor工人没有访问的工作区MATLAB桌面。为了解决这一问题,电话inputname之前parfor,如以下示例所示。

一个=“一个”;myFunction (a)函数name = inputname X = myFunction (a) (1);parfor我= 1:2 X (i)。(名)=我;结束结束

负载功能

的语法负载没有分配到一个输出结构内部不支持金宝appparfor循环。内部parfor,总是分配的输出负载一个结构。

输入参数个数nargout功能

以下内部使用不支持金宝appparfor循环:

  • 使用输入参数个数nargout没有一个函数参数

  • 使用narginchknargoutchk验证的输入或输出参数调用的函数正在执行

原因是工人没有访问的工作区MATLAB桌面。为了解决这一问题,之前调用这些函数parfor,如以下示例所示。

myFunction (“一个”,“b”)函数X = myFunction (a, b) nin =输入参数个数;parfor我= 1:2 X (i) = * nin;结束结束

- code脚本

你可以叫p从在一个脚本文件parfor循环,但不能包含一个称为p - code脚本parfor循环。为了解决这一问题,使用p代码函数代替- code脚本。

另请参阅

||

相关的话题