主要内容

与行主要数据的接口Matlab功能堵塞

数组布局对于集成,可用性和性能可能是重要的。万博1manbetxSimulink.®默认使用列主布局,就像Matlab功能块。但是,许多设备,传感器和库对其数据使用行主要数组布局。您可以使用该模型将模型直接应用于此数据编码器.CEVAL.控件中具有行主布局的函数Matlab功能块。

数组布局也可以影响性能。许多算法对于一个特定数组布局,更有效地执行内存访问。

仿真和代码生成中的行主要布局

Matlab功能块,你可以在块内指定行主数组布局。此规范发生在函数级,并且不会改变函数外部模型的数组布局。控件中指定的数组布局Matlab功能块适用于模拟和C / C ++代码生成。看在函数和类中指定数组布局

对于C / C ++代码生成使用万博1manbetxSimulink Coder™和嵌入式编码器®软件,您可以在模型级别指定数组布局,这些级别由此支持万博1manbetxMatlab功能块。有关在模型级别控制数组布局的详细信息,请参阅矩阵和数组的代码生成(万博1manbetx仿真软件编码器)。数组布局的模型代码生成设置对模拟没有影响。看阵列布局(万博1manbetx仿真软件编码器)。有关使用行主要布局的示例Matlab功能代码生成的块,请参见为包含MATLAB功能块的模型生成行主要代码(万博1manbetx仿真软件编码器)

Matlab功能块,函数级别的数组布局规范优先于模型的数组布局规范。但是,对于全局和持久变量,模型的数组布局规范优先于此。

阵列布局转换

马铃薯®和Sim万博1manbetxulink存储数据在列主布局默认。当您在不同的函数和不同的边界指定不同的数组布局时,该软件会根据需要自动插入数组布局转换。

例如,当您模拟模型或为使用列为主布局的模型生成代码时,模型包含Matlab功能使用行主布局的块,然后软件根据需要将块输入数据转换为行主,将块输出数据转换为列主。数组布局转换会影响性能。有关阵列布局的性能考虑的更多信息,请参见行阵列布局的代码设计

阵列布局和算法效率

对于某些算法,行主布局提供了更有效的内存访问。考虑将两个矩阵相加的函数。该算法通过显式的行和列遍历来执行加法。

功能[s] = addmatrix(a,b)编码器.Rowmajor;S = 0(大小(A));行= 1:尺寸(1)col = 1:大小(a,2)s(行,col)= a(行,col)+ b(行,col);结尾结尾

如果您在a中使用此代码Matlab功能块,代码生成导致此C代码的功能:

... / *使用行 - 主要* / for(行= 0;行<20;行++)生成的代码(col = 0; col <10; col ++){s [col + 10 *行] =[col + 10 *行] + b [col + 10 *行];}} ...

生成的代码使用公式对数组进行索引:

[col + 10 *行]

因为阵列存储在行主布局中,所以相邻的存储器元素通过单列增量分隔。这步幅对于算法等于一个。步幅长度是在连续存储器访问之间的存储器元件中的距离。较短的步幅长度提供更有效的内存访问。

对数据使用列为主的布局会导致更长的步长和更低的内存访问效率。要查看这个比较,请考虑为的生成的C代码AddMatrix.它使用了列主布局:

... / *使用列 - 主要* / for(行= 0;行<20;行++)生成addmatrix的代码{for(col = 0; col <10; col ++){s [行+ 20 * col] =[行+ 20 * col] + b [行+ 20 * col];}} ...

在列主布局中,列元素在生成的代码中的内存中是连续的。相邻的内存元素通过单行增量分隔并由公式索引:

[row + 20 * col]

但是,算法通过内部循环中的列迭代。因此,列主要C代码必须为每个连续的存储器访问进行20个元素的步幅。

提供最有效内存访问的数组布局取决于算法。对于这个算法,数据的行主布局提供了更有效的内存访问。该算法逐行遍历数据。因此,行主存储更有效。

n维数组的行主布局

可以对n维数组使用行主布局。当一个数组存储在row-major布局中,来自最后一个(最右边)维度或索引的元素在内存中是连续的。在列主布局中,来自第一个(最左边)维度或索引的元素是连续的。

考虑示例功能addmatrix3d.,它接受三维输入。

功能[S] = addMatrix3D(A,B) code . rowmajor;S = 0(大小(A));i = 1:尺寸(1)J = 1:尺寸(A,2)k = 1:大小(a,3)s(i,j,k)= a(i,j,k)+ b(i,j,k);结尾结尾结尾结尾

代码生成器会产生此C代码:

... / *行 - 主要布局* / for(i = 0; i <20; i ++){for(j = 0 ;j <10; j ++){for(k = 0; k <5; k ++){s [(k + 5 * j)+ 50 * i] = [(k + 5 * j)+ 50 * i] + b [(k + 5 * j)+ 50 * i];}}} ...

在行主要布局中,相邻的内存元素通过最后一个索引的单个增量分隔,k。内部的for循环迭代内存中仅由一个位置分隔的相邻元素。

删除coder.rowMajor调用并生成使用列主要布局的C代码:

... / *列 - 主要布局* / for(i = 0; i <20; i ++){for(j = 0 ;j <10; j ++){for(k = 0; k <5; k ++){s [(i + 20 * j)+ 200 * k] = [(i + 20 * j)+ 200 * k] + b [(i + 20 * j)+ 200 * k];}}} ...

在主列布局中,相邻的元素通过第一个索引的单个增量分隔,。内部for循环现在迭代在内存中分隔的200个位置的相邻元素上。长长的长度可能导致由于缓存未命中而导致性能下降。

因为算法通过最后一个索引迭代,因为k在内部for循环中,所生成的代码更长的步伐长度长得多,该代码具有多列级布局。对于这个算法,数据的行主布局提供了更有效的内存访问。

在外部函数调用中指定数组布局

要调用外部C/ c++函数,这些函数期望数据以特定的布局存储,请使用编码器.CEVAL.与之布局句法。如果您不使用此语法,则假定外部功能输入和输出默认使用列主要布局。

考虑一个外部C函数,设计为使用行主布局调用myCFunctionRM。要将此功能集成到您的代码中,请使用该函数调用该函数'-layout:rowmajor'或者“行”选择。该选项确保输入和输出数组按行主顺序存储。代码生成器会根据需要自动插入数组布局转换。

coder.ceval ('-layout:rowmajor','mycfunctionrm',coder.ref(in),coder.ref(out))

在使用行主要布局的MATLAB函数中,您可能会试图调用旨在使用列主要布局的外部功能。在这种情况下,使用'-layout:columnmajor'或者'-col'选择。

coder.ceval ('-layout:columnmajor','mycfunctioncm',coder.ref(in),coder.ref(out))

您可以在同一代码中执行行 - 主要和列主要函数调用。考虑该功能mymixedfn1.举个例子:

功能[e] = mymixedfn1(x,y)% # codegen编码器.Rowmajor;%指定Ceval呼叫的返回参数类型d =零(尺寸(x));e =零(尺寸(x));%包括外部C函数,使用行和列的主要coder.cinclude ('addmatrixrm.h');Coder.updateBuildInfo('addsourcefiles','addmatrixrm.c');coder.cinclude ('addmatrixcm.h');Coder.updateBuildInfo('addsourcefiles','addmatrixcm.c');%调用C函数使用行主顺序coder.ceval ('-layout:rowmajor','addmatrixrm',coder.rref(x),coder.rref(y),coder.wref(d));%调用C函数使用列-主顺序coder.ceval ('-layout:columnmajor','addmatrixcm',coder.rref(x),coder.rref(d),coder.wref(e));结尾

外部文件是:

addmatrixrm.h.

addMatrixRM.c

addMatrixCM.h

addMatrixCM.c

另请参阅

||||

相关话题