中变量分类parfor
循环
概述
MATLAB®编码器™类中的变量进行分类parfor
-loop转换为下表中的类别之一。它不支持无法分类的变量。万博1manbetx如果一个parfor
-loop包含不能唯一分类的变量,如果变量违反了其类别限制,则使用parfor
-loop生成错误。
分类 | 描述 |
---|---|
循环 | 作为数组的循环索引 |
切片 | 一种数组,其段由循环的不同迭代操作 |
广播 | 在循环之前定义的变量,其值在循环内部使用,但不在循环内部赋值 |
减少 | 在循环的迭代中累加一个值,而不考虑迭代顺序 |
临时 | 在循环内部创建的变量,但与切片或还原变量不同,在循环外部不可用 |
这些变量分类出现在下面的代码片段中:
= 0;c =π;z = 0;r =兰德(10);Parfor i=1:10 a=i;% 'a'是一个临时变量z=z+i;% 'z'是约简变量b(i)=r(i);% 'b'是一个切片输出变量;% 'r'是切片输入变量,如果i<=c % 'c'是广播变量d=2*a;% 'd'是一个临时变量
切变量
一个切变量它的值可以被分割成几个部分,还是片,然后由不同的线程分别操作。循环的每次迭代都在数组的不同切片上工作。
在下一个例子中,一片一个
由该数组中的一个元素组成:
parfor i = 1:长度(A) B(i) = f(A(i));结束
切片变量的特征
A中的变量parfor
如果-loop具有以下特征,则被切片:
第一级索引的类型-第一级索引是圆括号,
()
.固定索引列表——在第一级括号内,对于给定变量的所有出现,索引列表都是相同的。
索引的形式——在变量的索引列表中,只有一个索引涉及循环变量。
数组的形状——在给切片变量赋值时,赋值的右边不是
[]
或”
(这些操作符表示删除元素)。
一级索引的类型.对于切片变量,第一级索引用圆括号括起来,()
.例如,(…)
.如果使用点表示法引用变量,A.x
时,变量未被切片。
变量一个
左边没有切片;变量一个
右边是切片图:
A.q(我12)(我12)。q
固定索引列表.在切片变量索引的第一级括号内,对于给定变量的所有出现,索引列表都是相同的。
变量B
左边没有切片,因为B
索引为我
而且我+ 1
在不同的地方。变量B
右边是切片。
B(i) = B(i+1) +1;结束 |
B(i+1) = B(i+1) +1;结束 |
索引形式.在切片变量的索引列表中,一个索引的形式为我
,我+ k
,i (k
,k +我
,或k-i
.
我
是循环变量。k
是常量或简单(非索引)变量。其他所有索引都是常量、简单变量、冒号或
结束
.
当使用其他变量和循环变量一起索引数组时,不能在循环中设置这些变量。这些变量在整个执行过程中是不变的parfor
声明。不能将循环变量与其本身组合起来形成索引表达式。
在下面的例子中,我
是循环变量,j
而且k
为非索引变量。
变量A未切片 | 变量A被切片 |
---|---|
A(i+f(k),j,:,3) A(i,20:30,end) A(i,:,s.field1) |
A(i+k,j,:,3) A(i,:,end) A(i,:,k) |
阵列形状.切片变量必须保持恒定的形状。在下面的例子中,变量一个
未切片:
A(i,:) = [];A(end + 1) = i;
广播变量
一个广播变量是循环变量以外的变量,也不是在循环内未修改的切片变量。
减少变量
一个减少变量累积一个依赖于所有迭代的值,但与迭代顺序无关。
这个例子显示了parfor
-循环使用标量约简赋值。它使用约简变量x
把…的总数加起来10
循环的迭代。线程上迭代的执行顺序并不重要。
X = 0;Parfor I = 1:10 x = x + I;结束x
在哪里expr
为MATLAB表达式,约简变量出现在赋值语句的两侧。
X = X + expr |
X = expr + X |
X = X - expr |
看到约简函数的约简赋值、结合律和交换律 |
X = X .* expr |
X = expr .* X |
X = X * expr |
X = expr * X |
X = X & expr |
X = expr & X |
X = X | expr |
X = expr | X |
X = min(X, expr) |
X = min(expr, X) |
X = max(X, expr) |
X = max(expr, X) |
X = f (X, expr) 函数 f 必须是用户自定义的函数。 |
X = f(expr, X) 看到约简函数的约简赋值、结合律和交换律 |
每个允许的语句都被称为a减少作业.约简变量只能出现在这种类型的赋值中。
下面的示例展示了简化变量的典型用法X
:
X =…;做一些初始化X parfor i = 1:n X = X + d(i);结束
这个循环等价于下面,其中每个d(我)
由不同的迭代计算:
X = X + d(1) +…+ d (n)
如果循环是正则的为
-loop,变量X
在每次迭代中,都将在进入循环之前或从循环的前一次迭代中获得其值。但是,这个概念并不适用于parfor
循环。
在一个parfor
-loop,的值X
不会在每个线程中直接更新。而是增加d(我)
都是在每个线程中完成的,用我
的子集1: n
正在该线程上执行。然后软件将结果累积成X
.
同样,减法为:
r = r < op > x(我)
r = r < op > x (1)] < op >(2)…< op > x (n)
< op >
首先应用于x(1)……(n)
,则将部分结果应用于r
.
如果操作< op >
需要两个输入,它应该满足以下标准之一:
取两个论证
typeof (x (i))
并返回typeof (x (i))
取一个论证
typeof(右)
其中一个typeof (x (i))
并返回typeof(右)
变量约简规则
在所有约简分配中使用相同的约简函数或操作。对于约简变量,必须在该变量的所有约简分配中使用相同的约简函数或操作。在下面的示例中,使用parfor
左边的-loop是无效的,因为约简赋值使用+
在一个例子中,和*
在另一个。
无效使用约简变量 | 约简变量的有效使用 |
---|---|
如果A > 5*k A = A + 1;else A = A * 2;结束 |
如果A > 5*k A = A * 3;else A = A * 2;结束 |
约简函数参数和返回类型的限制。减少r = r < op > x(我)
,应该采取的论点typeof (x (i))
并返回typeof (x (i))
或者取论证typeof(右)
而且typeof (x (i))
并返回typeof(右)
.
在下面的例子中,在无效循环中,r
是定点类型和2
不是。要修复此问题,请执行强制转换2
与…是同一类型r
.
无效使用约简变量 | 约简变量的有效使用 |
---|---|
function r= fiops(in) r=fi(in,'WordLength',20,…“FractionLength”,14日……“SumMode”、“SpecifyPrecision’,……“SumWordLength”,20日……“SumFractionLength”,14日……“ProductMode”、“SpecifyPrecision’,……“ProductWordLength”,20日……“ProductFractionLength”,14);parfori = 1:10 r = r*2;结束 |
r = fi(“字”,20日…“FractionLength”,14日……“SumMode”、“SpecifyPrecision’,……“SumWordLength”,20日……“SumFractionLength”,14日……“ProductMode”、“SpecifyPrecision’,……“ProductWordLength”,20日……“ProductFractionLength”,14);T = r.数字类型;F = r.fimath; parfor i = 1:10 r = r*fi(2,T,F); end |
在下面的例子中,约简函数fcn
无效,因为它不处理输入时的情况u
是定点。(+
而且*
操作是自动多态的。)的多态版本fcn
来处理预期的输入类型。
无效使用约简变量 | 约简变量的有效使用 |
---|---|
函数[y0, y1, y2] = pfuserfcn(u) y0 = 0;Y1 = 1;[F, N] = fiprops();y2 = fi(1,N,F);Parfor (i=1: number (u),12) y0 = y0 + u(i);y = y * u(i);Y2 = fcn(Y2, u(i));结束结束函数y = fcn(u, v) y = u * v;结束 |
函数[y0, y1, y2] = pfuserfcn(u) y0 = 0;Y1 = 1;[F, N] = fiprops();y2 = fi(1,N,F);Parfor (i=1: number (u),12) y0 = y0 + u(i);y = y * u(i);Y2 = fcn(Y2, u(i));如果isa(u,'double') y = u * v,则处理type double %和fi函数y = FCN (u, v)的输入;else [F, N] = fiprops();y = u * fi(v,N,F); end end function [F, N] = fiprops() N = numerictype(1,96,30); F = fimath('ProductMode',... 'SpecifyPrecision',... 'ProductWordLength',96); end |
约简函数的约简赋值、结合律和交换律
减少作业.MATLAB编码器不允许在中的任何地方读取约简变量parfor
-loop除了在还原语句中。在下面的例子中,调用foo(右)
减算报表之后r = r +我
导致循环无效。
函数r = temp %#代码原r = 0;Parfor i=1:10 r = r + i;foo (r);结束结束
约简赋值中的结合性。如果使用用户定义的函数f
在定义约简变量时,得到的确定性行为parfor
-loops,约简函数f
一定是结合律。
请注意
如果f
不是结合律,MATLAB编码器不生成错误。您必须编写符合此建议的代码。
函数是结合律f
必须全部满足以下条件吗一个
,b
,c
:
F (a, F (b,c)) = F (F (a,b),c)
约简分配中的交换性。一些联想函数,包括+
,.
,最小值
,马克斯
,也是可交换的。也就是说,它们满足以下所有条件一个
而且b
:
F (a,b) = F (b,a)
这个函数f
约简分配必须是可交换的。如果f
不是可交换的,不同的循环执行可能会导致不同的结果。
除非f
是已知的非交换性内置的,软件假定它是交换性的。
临时变量
一个临时变量是直接非索引赋值的目标变量,但不是约简变量。在下面parfor
循环,一个
而且d
是临时变量:
A = 0;Z = 0;R = rand(1,10);Parfor I = 1:10 a = I;%变量a为临时变量z = z + i;如果I <= 5 d = 2*a;%变量d为临时结束结束
与之相反的是为
的每次迭代之前parfor
循环,MATLAB编码器有效地清除临时变量。因为迭代必须是独立的,所以临时变量的值不能从循环的一个迭代传递到另一个迭代。类的体中必须设置临时变量parfor
-loop,以便它们的值在每次迭代中分别定义。
对象上下文中的临时变量parfor
语句不同于存在于循环之外的同名变量。
未初始化的临时变量
因为临时变量在每次迭代开始时都被清除,MATLAB编码器可以检测在循环迭代中设置临时变量之前使用临时变量的某些情况。在这种情况下,MATLAB编码器发出一个静态错误而不是运行时错误,因为如果将发生运行时错误,允许继续执行几乎没有意义。例如,假设你写:
B =真;Parfor I = 1:n if b && some_condition(I) do_something(I);B = false;结束……结束
这个循环作为普通循环是可以接受的为
-loop,但作为一个parfor
循环,b
是临时变量,因为它直接作为循环内赋值的目标出现。因此,它在每次迭代开始时都被清除,因此它在条件下的使用如果
是未初始化的。(如果你改变parfor
来为
的值。b
假设循环按顺序执行,这样do_something(我)
的较低值执行我
直到b
设置假
.)