生成代码,使用行阵列布局
阵列布局可以重要的集成、可用性和性能。代码生成器生成的代码,使用默认列为主的布局。然而,许多设备、传感器和库使用行阵列布局数据。可以将代码直接应用到这些数据通过生成代码使用行布局。阵列布局也会影响性能。许多算法更有效地执行内存访问一个特定的阵列布局。
你可以在命令行中指定行阵列布局,与代码生成配置属性,或使用MATLAB®编码器™应用。您还可以指定行布局或列为主的布局为单独的函数和类。入口点的输入和输出(顶级)函数都必须使用相同的阵列布局。
指定行布局
考虑这个函数添加两个矩阵。算法执行通过显式添加行和列遍历。
函数[S] = addMatrix (A, B)% # codegenS = 0(大小(A));为行= 1:尺寸(1)为坳= 1:尺寸(2)年代(行,坳)=(行,上校)+ B(行,坳);结束结束
生成C代码addMatrix
通过使用-rowmajor
选择。指定输入参数的形式使用arg游戏
选择和启动代码生成报告。
codegenaddMatrixarg游戏{的(20、10)的(20、10)}配置:自由-launchreport-rowmajor
另外,为行布局通过修改配置代码RowMajor
参数代码生成配置对象。您可以使用这个参数与任何类型的配置对象:自由
,墨西哥人
,dll
,或exe
。
cfg = coder.config (“自由”);cfg。RowMajor = true;codegenaddMatrixarg游戏{的(20、10)的(20、10)}配置cfg-launchreport
在这个C代码代码生成的结果:
…/ *为addMatrix使用所生成的代码行* /(行= 0;行< 20;行+ +){(col = 0;坳< 10;坳+ +){S[坳+ 10 *行]=[坳+ 10 *行]+ B (col + 10 *行);}}…
指定的行布局MATLAB编码器应用:
打开生成对话框。在生成代码页面,点击生成箭头。
点击更多的设置。
在内存选项卡,设置阵列布局:
行
。
来验证您的生成的代码使用行布局,比较的数组索引的数组索引生成的代码的代码,使用列为主的布局。您还可以使用n维索引生成代码。n维索引可以使阵列布局的差异更明显。有关更多信息,请参见使用n维索引生成代码。
MATLAB数据存储在默认列为主的布局。当你调用一个函数生成的墨西哥人使用行布局,软件自动将输入的数据列为主的布局行布局。墨西哥人函数返回的输出数据转换回列为主的布局。为独立的自由
,dll
,exe
代码生成代码生成器假定入口点函数的输入和输出存储阵列布局相同的功能。
阵列布局和算法效率
对于某些算法,行布局提供了更高效的内存访问。考虑到C代码addMatrix
使用行布局。生成的代码使用的数组索引公式:
(col + 10 *行)
因为数组存储在存储布局,相邻的内存元素由单一列增量。的步幅等于1的算法。步幅的距离在内存中元素之间的连续内存访问。缩短步幅提供更高效的内存访问。
使用列为主的布局数据结果的时间步长和低效率的内存访问。看到这种比较,生成代码,使用列为主的布局:
codegenaddMatrixarg游戏{的(20、10)的(20、10)}配置:自由-launchreport
代码生成生成C代码:
…/ *为addMatrix所生成的代码使用列为主* /(行= 0;行< 20;行+ +){(col = 0;坳< 10;坳+ +){S[行+ 20 *坳]=[行+ 20 *坳]+ B[行+ 20 *坳];}}…
在列为主的布局,列元素是连续的在内存中生成的代码。相邻的内存元素由单行增量和索引的公式:
(行+ 20 *坳)
然而,该算法遍历列在内部循环。因此,列为主的C代码必须跨连续20个元素为每个内存访问。
阵列布局,提供最有效的内存访问取决于算法。对于这个算法,数据行布局提供更高效的内存访问。该算法遍历数据行,行。行存储是因此更有效率。
行布局n维数组
您可以使用行布局n维数组。数组存储在存储布局时,从最后一个元素(右边的)维度或指标是连续的在内存中。在列为主的布局,从第一个元素(最左边的)维度或指标是连续的。
考虑函数的例子addMatrix3D
,接受三维输入。
函数[S] = addMatrix3D (A, B)% # codegenS = 0(大小(A));为i = 1:尺寸(1)为j = 1:尺寸(2)为k = 1:尺寸(3)年代(i, j, k) = (i, j, k) + B (i, j, k);结束结束结束结束
生成的代码使用行布局:
codegenaddMatrix3Darg游戏{(20、10、5)、人(20、10、5)}配置:自由-launchreport-rowmajor
代码生成器生成C代码:
…/ * * /行布局(i = 0;我< 20;我为(+ +){j = 0;j < 10;j + +) {(k = 0;k < 5;k + +) {S [(k + 5 * j) + 50 *我]= [(k + 5 * j) + 50 *我]+ B [(k + 5 * j) + 50 *我);}}}…
行布局,相邻的内存由单一元素增加最后的指数,k
。内循环遍历相邻元素隔开在内存中只有一个位置。比较的差异和生成的代码,使用列为主的布局:
…* / / *列为主的布局(i = 0;我< 20;我为(+ +){j = 0;j < 10;j + +) {(k = 0;k < 5;k + +) {S [(i + 20 * j) + 200 * k] = [(i + 20 * j) + 200 * k) + B [(i + 20 * j) + 200 * k);}}}…
在列为主的布局,相邻元素由单一的第一个索引的增量,我
。现在的内循环遍历相邻元素在内存中由200个职位。漫长的步幅由于缓存缺失会导致性能下降。
因为算法遍历最后指数,k
,在内部循环,步幅是生成的代码,使用更长的时间列为主的布局。对于这个算法,数据行布局提供更高效的内存访问。
在外部函数调用指定阵列布局
调用外部C / c++函数期望数据存储与特定的布局,使用coder.ceval
与布局
语法。如果你不使用这个语法,外部函数的输入和输出假设默认使用列为主的布局。
考虑外部C函数设计为使用行布局myCFunctionRM
。将这个函数集成到您的代码,调用函数使用“布局:rowMajor”
或“行”
选择。这个选项可以确保输入和输出数组存储在存储顺序。代码生成器自动插入数组布局转换。
coder.ceval (“布局:rowMajor”,“myCFunctionRM”,coder.ref coder.ref ())
在MATLAB函数使用行布局,你可能试图调用外部函数设计为使用列为主的布局。在这种情况下,使用“布局:columnMajor”
或“上校”
选择。
coder.ceval (“布局:columnMajor”,“myCFunctionCM”,coder.ref coder.ref ())
您可以执行行和列为主函数调用相同的代码。考虑到功能myMixedFn1
作为一个例子:
函数[E] = myMixedFn1 (x, y)% # codegen%为ceval指定类型的返回参数调用D = 0(大小(x));E = 0(大小(x));%包括外部C函数使用行和列为主coder.cinclude (“addMatrixRM.h”);coder.updateBuildInfo (“addSourceFiles”,“addMatrixRM.c”);coder.cinclude (“addMatrixCM.h”);coder.updateBuildInfo (“addSourceFiles”,“addMatrixCM.c”);%使用行顺序调用C函数coder.ceval (“布局:rowMajor”,“addMatrixRM”,…coder.rref (x) coder.rref (y), coder.wref (D));%调用C函数,使用列为主的秩序coder.ceval (“布局:columnMajor”,“addMatrixCM”,…coder.rref (x) coder.rref (D), coder.wref (E));结束
外部文件:
来生成代码,请输入:
codegen配置:自由myMixedFn1arg游戏{的(20、10)的(20、10)}-rowmajor-launchreport
另请参阅
coder.columnMajor
|coder.rowMajor
|coder.ceval
|coder.isRowMajor
|coder.isColumnMajor
|codegen