主要内容

展开循环和parfor循环

当代码生成器展开循环或parfor-loop,它不会在生成的代码中生成循环,而是为每次迭代生成循环体的副本。对于小而紧的循环,展开可以提高性能。然而,对于大型循环,展开会显著增加代码生成时间并生成低效代码。

-使用循环展开coder.unroll

代码生成器使用启发式来确定何时展开循环。若要强制展开循环,请使用coder.unroll.这只影响紧接其后的循环coder.unroll.例如:

函数Z = call_myloop()% # codegenZ = myloop(5);结束函数B = myloop(n) B = 0 (1,n);coder.unroll ();I = 1:n b(I)= I +n;结束结束

下面是for循环生成的代码:

Z [0] = 6.0;Z [1] = 7.0;Z [2] = 8.0;Z [3] = 9.0;Z [4] = 10.0;

控制-loop被展开,使用coder.unroll国旗论点。例如,仅当迭代次数小于10时才展开循环。

函数Z = call_myloop()% # codegenZ = myloop(5);结束函数B = myloop(n) unroll_flag = n < 10;B = 0 (1,n);coder.unroll (unroll_flag);I = 1:n b(I)= I +n;结束结束

展开-loop时,代码生成器必须能够确定循环。例如,以下代码的代码生成失败,因为的值n在代码生成时不知道。

函数B = myloop(n) B = 0 (1,n);coder.unroll ();I = 1:n b(I)= I +n;结束结束

设置所有环路展开阈值循环和parfor-在MATLAB代码

如果一个-loop之前没有coder.unroll,代码生成器使用循环展开阈值来确定是否自动展开循环。如果循环迭代的次数小于阈值,则代码生成器展开循环。如果迭代次数大于或等于阈值,代码生成器将生成一个循环。通过使用循环展开阈值,也可以展开parfor循环。

缺省值为5.通过修改这个阈值,可以对循环展开进行微调。修改阈值。

不像coder.unroll指令,阈值适用于所有-循环在你的MATLAB代码。这个阈值也适用于某些情况-在代码生成期间产生的循环。

对于单个循环,acoder.unroll指令优先于循环展开优化。

展开简单的循环

考虑这个函数:

函数[x,y] = call_myloops()% # codegenX = myloop1(5);Y = myloop2(5);结束函数B = myloop1(n) B = 0 (1,n);I = 1:n b(I)= I +n;结束结束函数B = myloop2(n) B = 0 (1,n);I = 1:n b(I)= I *n;结束结束

将循环展开阈值设置为6,然后生成一个静态库,运行:

cfg = code . codeconfig;cfg。LoopUnrollThreshold = 6;codegencall_myloops配置cfg

的生成代码循环。代码生成器展开两者循环。

X [0] = 6.0;Y [0] = 5.0;X [1] = 7.0;Y [1] = 10.0;X [2] = 8.0;Y [2] = 15.0;X [3] = 9.0;Y [3] = 20.0;X [4] = 10.0;Y [4] = 25.0;

展开嵌套循环

假设你的MATLAB代码有两个嵌套循环。

  • 如果内部循环的迭代次数小于阈值,代码生成器将首先展开内部循环。随后,如果两个循环的迭代次数的乘积也小于阈值,则代码生成器展开外部循环。否则,代码生成器生成外部循环。

  • 如果内部循环的迭代次数等于或大于阈值,代码生成器将同时生成循环。

这种行为可以推广到多个嵌套循环。

考虑函数nestedloops_1有两个嵌套循环:

函数Y = nestedloops_1% # codegenY = 0 (2,2);I = 1:2J = 1:2 y(i, J) = i+ J;结束结束结束

nestedloops_1将循环展开阈值设置为默认值5.的生成代码循环。代码生成器展开两者-loops,因为两个循环的迭代次数的乘积为4,小于阈值。

Y [0] = 2.0;Y [2] = 3.0;Y [1] = 3.0;Y [3] = 4.0;

现在,为函数生成代码nestedloops_2将循环展开阈值设置为默认值5

函数Y = nestedloops_2% # codegenY = 0 (3,2);I = 1:3J = 1:2 y(i, J) = i+ J;结束结束结束

内循环的迭代次数小于阈值。代码生成器展开内部循环。但是两个循环的迭代次数的乘积是6,大于阈值。因此,代码生成器为外部生成代码循环。的生成代码循环。

For (i = 0;I < 3;I ++) {y[I] = (double) I + 2.0;Y [i + 3] = ((double)i + 1.0) + 2.0;}

展开parfor循环

考虑这个MATLAB函数:

函数[x,y] = parallel_loops()% # codegenX = myloop1(5);Y = myloop2(6);结束函数B = myloop1(n) B = 0 (1,n);parfor(i = 1:n) b(i)=i+n;结束结束函数B = myloop2(n) B = 0 (1,n);parfor(1:n) b(i)=i*n;结束结束
将循环展开阈值设置为6,然后生成静态库。
cfg = code . codeconfig;cfg。LoopUnrollThreshold = 6;codegenparallel_loops配置cfg
这是生成的代码。

静态无效myloop1(双b[5]) {b[0] = 6.0;B [1] = 7.0;B [2] = 8.0;B [3] = 9.0;B [4] = 10.0;} static void myloop2(double b[6]) {int i;#pragma omp parallel for num_threads(omp_get_max_threads()) for (i = 0;I < 6;I ++) {b[I] = ((double) I + 1.0) * 6.0;}} void parallel_loops(double x[5], double y[6]) {if (!isInitialized_parallel_loops) {parallel_loops_initialize(); } myloop1(x); myloop2(y);}

代码生成器只展开parfor-loop迭代5次,小于阈值。

另请参阅

相关的话题