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)结尾结尾
以下代码显示了一个简单的示例。用t
和TOC.
计算所需的计算时间。
一个= 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
循环。用t
和TOC.
计算所需的计算时间。用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
没有函数参数
使用narginchk
或Nargoutchk.
验证当前执行的函数调用中输入或输出参数的数量
原因是工人无法访问MATLAB桌面的工作空间。要解决此问题,请以前调用这些函数par
,如以下示例所示。
myfunction(“一个”那“b”的)函数X = myFunction(a,b) nin = nargin;parX(i) = i*nin;结尾结尾
您可以从a中调用p代码脚本文件par
-loop,但p代码脚本不能包含一个par
循环。要解决此问题,请使用p代码函数而不是p代码脚本。