主要内容

嵌套par为了- 砍掉和其他par需求

嵌套par- 酥油

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

pari = 1:10parJ = 1:5...结尾结尾

提示

你不能筑巢par直接在另一个内par循环。一种par-loop可以调用包含一个函数par- 但是,但你没有得到任何额外的并行性。

代码分析器在MATLAB®编辑标志使用par在另一个里面par-环形:

你不能筑巢par-loops,因为并行化只能在一个级别上执行。因此,选择并行运行哪个循环,并将另一个循环转换为a为了循环。

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

  • 并行处理会引发开销。通常,您应该并行运行外环,因为开销仅发生一次。如果并行运行内部循环,则每个若干par执行会引发一个开销。看将嵌套的for循环转换为parfor循环以获取如何度量并行开销的示例。

  • 确保迭代的数量超过工作人员的数量。否则,您不会使用所有可用的worker。

  • 试着平衡par-loop迭代时间。par试图补偿一些负载不平衡。

提示

总是并行地运行最外层的循环,因为这样可以减少并行开销。

您还可以使用使用的功能par把它嵌入par循环。并行化仅在外层处发生。在以下示例中,调用函数MyFun.m在外面par循环。内par-loop嵌入中MyFun.m按顺序运行,而不是并行运行。

par我= 1:10 myfun(i)结尾函数myfun(i)parJ = 1:5...结尾结尾

提示

嵌套par- 砍伐通常给你没有计算好处。

转换嵌套为了- 换来par- 酥油

嵌套循环的典型用法是使用单循环变量来索引一维数组,然后使用嵌套循环变量来索引另一维数组。基本形式为:

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

以下代码显示了一个简单的示例。用tTOC.计算所需的计算时间。

一个= 100;t为了我= 1:100为了if (a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or结尾结尾TOC.
经过时间为49.376732秒。

您可以并行化这两个嵌套循环中的任何一个,但不能并行运行这两个循环。原因是并行池中的工作人员不能启动或访问更多的并行池。

如果循环计数一世转换为par-Loop,然后池中的每个工作人员都使用该池中执行嵌套环路j循环计数器。这j循环本身不能作为一个par在每个工人。

因为并行处理会产生开销,所以必须仔细选择要转换内部还是外部为了- 为A.par循环。以下示例显示了如何测量并行开销。

首先只转换为了- 为A.par循环。用tTOC.计算所需的计算时间。用ticbytes.tocBytes测量有多少数据被传输到并行池中的工作人员或从工作人员那里。

运行新代码,然后再运行它。第一个运行比后续运行慢,因为并行池需要一些时间才能启动并使工人可用的代码。

一个= 100;抽搐ticBytes (gcp);par我= 1:100为了if (a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or结尾结尾tocbytes(GCP)TOC
BytessentToworks BytesreceivedFromworkers __________________ _______________________ 3 32984 24512 2 33784 24512 2 3 3 33784 25312 4 33784 2312 2312 26112 2 33784 25312 4 33784 25312 4 33784 25312 4 33784 25312 4 33784 25312 4 3 33784 23122 2612 26112总计1.3514E + 05 1.0125E + 05经过的时间为14.130674秒。

接下来只转换循环到A.par循环。测量所需的时间和在前面的情况下传输的数据。

一个= 100;抽搐ticBytes (gcp);为了我= 1:100parif (a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or a = ref (a, 1) or结尾结尾tocbytes(GCP)TOC
BytessentToworks BytesreceivedFrom Wherwworkers _______________________________________ 1.3496C + 05 5.487E + 05 5.4858E + 05 5.4858E + 05 5.4858E + 05 5.4858E + 05 3 1.3670 + 05 5.6034C + 05 5.6034C + 05 4 1.3470 + 05 5.4770 + 05 5.4717E + 05 5.4717E + 05总计5.4144E + 06 2.2048E + 06经过时间是48.631737秒。

如果转换循环到A.par-loop时,传输的时间和数据量都比并行外环路大得多。在这种情况下,运行的时间几乎与嵌套的时间相同为了循环的例子。这种加速比并行地运行外部循环要小,因为需要更多的数据传输,因此需要更多的并行开销。因此,如果你执行与运行串行相比,并行循环,无需计算效益为了循环。

如果想减少并行开销并加快计算速度,可以并行地运行外部循环。

如果转换循环,然后,外循环的每个迭代都会启动单独的par循环。也就是说,内环转换创建100par循环。每个倍数par执行突出了开销。如果要减少并行开销,则应替换外部循环,因为开销仅发生一次。

提示

如果要加快代码,请始终并行运行外环,因为您可以减少并行开销。

嵌套为了-循环:需求和限制

如果要转换嵌套为了- 为A.par-Loop,您必须确保循环变量正确分类,请参阅排除parfor循环中的变量.如果您的代码不遵守标记为的指南和限制必需的,你得到一个错误。Matlab在读取代码时捕获一些这些错误。这些错误被标记为要求(静态)

要求(静态):你必须定义一个为了- 嵌套在一个par-循环通过常量或广播变量。

在下面的示例中,左边的代码无法工作,因为您定义了为了- 通过函数调用。右侧的代码通过首先定义外部的广播或常量变量来提供解决方法par-环形:

无效的 有效的
A = 0 (100, 200);pari = 1:尺寸(a,1)为了A(i, j) = i + j;结尾结尾
A = 0 (100, 200);n = size(A, 2);pari = 1:尺寸(a,1)为了j = 1:n(i,j)= i + j;结尾结尾
要求(静态):嵌套的索引变量为了-Loop必须永远不会被除其中的明确分配为了陈述。

在此限制之后是必需的。如果嵌套为了-loop变量在a中的任何位置都更改par-loop而不是by its为了声明,该地区索引为了-Loop变量不保证在每个工人上可用。

左侧的代码无效,因为它试图修改嵌套的值为了-loop变量j在循环的身体里。右侧的代码通过分配嵌套来提供解决方法为了-loop变量到临时变量T.,然后更新T.

无效的 有效的
a =零(10);pari = 1:10为了A(i, j) = 1;j = + 1;结尾结尾
a =零(10);pari = 1:10为了A(i, j) = 1;t = j;T = T + 1;结尾结尾
要求(静态):您无法索引或下标为了循环变量。

在此限制之后是必需的。如果是嵌套为了-loop变量是索引的,无法保证迭代是独立的。

左侧的示例无效,因为它尝试索引嵌套为了-loop变量j.右边的示例删除了这个索引。

无效的 有效的
a =零(10);pari = 1:10为了J = 1:10 J(1);结尾结尾
a =零(10);pari = 1:10为了j = 1:10 j;结尾结尾
要求(静态):当使用嵌套为了-loop变量用于索引切片数组,必须以普通形式使用该变量,而不能作为表达式的一部分。

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

无效的 有效的
a =零(4,11);pari = 1:4为了j = 1:10 a(i,j + 1)= i + j;结尾结尾
a =零(4,11);pari = 1:4为了A(i, j) = i + j - 1;结尾结尾
要求(静态):如果您使用嵌套为了-loop来索引切片数组,则不能在par循环。

在以下示例中,左侧的代码不起作用,因为一种在嵌套的为了循环。右边的代码工作是因为V.被分配给一种在嵌套循环之外:

无效的 有效的
a =零(4,10);pari = 1:4为了j = 1:10 a(i,j)= i + j;结尾disp(a(i,j))结尾
a =零(4,10);pari = 1:4 v =零(1,10);为了v(J) = I + J;结尾DISP(v(j))a(i,:) = v;结尾

par循环的限制

嵌套功能

身体par-loop不能引用嵌套函数。但是,它可以通过函数句柄调用嵌套函数。试试下面的例子。请注意,a(idx)= nfcn(idx)在里面par-loop不起作用。你必须使用Feval.举行援助FCN.处理的par循环体。

函数a = pfeg.函数OUT = NFCN(IN)OUT = 1 +;结尾fcn = @nfcn;paridx = 1:10 a(idx)= feval(fcn,Idx);结尾结尾
>> PFEG使用“本地”配置文件启动并行池(Parpool)...连接到4名工人。ans = 2 3 4 5 6 7 8 9 10 11

提示

如果使用函数句柄,请参阅a内的嵌套函数par-loop,然后在工人之间不同步外部范围变量的值。

嵌套par- 酥油

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

嵌套SPMD.陈述

身体par-loop无法包含SPMD.声明,和一个SPMD.语句不能包含par循环。原因是worker不能启动或访问更多的并行池。

休息返回陈述

身体par循环不能包含休息返回语句。考虑Parfeval.parfevalOnAll相反,因为你可以使用取消在他们身上。

全局和持久变量

身体par循环不能包含全球执着的变量声明。原因是这些变量在工人之间不同步。您可以使用全球执着的函数中的变量,但它们的值仅对创建它们的工作者可见。代替全球变量,使用函数参数共享值是一种更好的实践。

要了解更多关于可变需求的信息,请参见排除parfor循环中的变量

脚本

如果脚本介绍变量,则无法从中调用此脚本par- 或者SPMD.陈述。原因是此脚本会导致透明度违规。有关更多详细信息,请参阅确保循环或SPMD语句中的透明度

匿名功能

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

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

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

InputName.职能

使用InputName.返回内部不支持与参数编号对应的工作空间变量名称金宝apppar循环。原因是par工人无法访问Matlab桌面的工作空间。解决此问题,致电InputName.par,如以下示例所示。

A =“一个”;myfunction(a)函数x = myfunction(a)name = inputname(1);pari=1:2 X(i).(name) =1;结尾结尾

加载职能

语法加载不支持未分配输出结构的内部金宝apppar循环。内部par,始终分配输出加载到一个结构。

纳尔加nargout职能

内部不支持以下用途金宝apppar- 砍伐:

  • 使用纳尔加nargout没有函数参数

  • 使用narginchkNargoutchk.验证当前执行的函数调用中输入或输出参数的数量

原因是工人无法访问MATLAB桌面的工作空间。要解决此问题,请以前调用这些函数par,如以下示例所示。

myfunction(“一个”“b”的)函数X = myFunction(a,b) nin = nargin;parX(i) = i*nin;结尾结尾

P代码脚本

您可以从a中调用p代码脚本文件par-loop,但p代码脚本不能包含一个par循环。要解决此问题,请使用p代码函数而不是p代码脚本。

也可以看看

||

相关的话题