主要内容

生成使用n维索引的代码

默认情况下,代码生成器对数组使用一维索引。代码生成器在C/ c++代码中为MATLAB中的n维数组创建一维数组®代码。您可以使用n维索引来提高可读性,并根据生成的代码调整接口。

此表显示了使用n维索引和不使用n维索引时生成的代码之间的差异。

MATLAB代码

生成的C代码(默认)

生成启用N-D索引的C代码

A = 0 (2,4,6)
一个[48]
  • 以列为主的数组布局(默认):

    一个[6][4][2]
  • 启用行主数组布局:

    一个[2][4][6]

n维索引的索引顺序是颠倒的,因为MATLAB生成的代码默认使用列主数组布局。要切换索引的顺序,可以启用行主数组布局。

将n维数组转换为一维数组也称为数组压扁.在计算机存储器中,所有数据都以一维数组的形式存储。索引的选择不会改变计算结果。但是,如果代码的输入或输出是数组,则生成代码的接口可以更改。

启用n维索引:

  • 使用-preservearraydims选择:

    codegen喷火-preservearraydims
  • 设置PreserveArrayDimensions属性的代码生成配置对象真正的.例如:

    CFG = code .config(“自由”);cfg。PreserveArrayDimensions = true;codegen喷火配置cfg

的n维索引MATLAB编码器™应用:

  • 导航到生成代码页中的代码生成工作流。

  • 打开生成对话框生成箭头

  • 点击更多的设置

  • 内存选项卡,选择保留数组尺寸复选框。

使用n维索引和行主布局提高可读性

n维索引可以使您更容易地将生成的C/ c++代码追溯到MATLAB代码。代码生成器保留原始数组的维度,而不是将数组转换为一维。此外,可以指定行主布局,使代码外观更加直观。

考虑MATLAB函数addMatrices,将两个矩阵逐个元素相加:

函数sum = addMatrices(A,B)% # codegensum = code .nullcopy(A);row = 1:size(A,1)size(A,2) sum(row,col) = A(row,col) + B(row,col);结束结束

生成以下代码addMatrices它作用于2 × 4数组。启用n维索引和行主数组布局:

CFG = code .config(“自由”);cfg。PreserveArrayDimensions = true;cfg。RowMajor = true;codegenaddMatricesarg游戏{的(2、4)的(2、4)}配置cfg-launchreport

代码生成生成带有显式二维数组索引的代码:

/* N-d索引on, row-major on */ void addMatrices(double A[2][4], double B[2][4], double sum[2][4]) {int row;int上校;For (row = 0;行< 2;Row ++) {for (col = 0;Col < 4;坳+ +){总和(行)(col) =(行)(col) + B(行)(col);}}}

的生成代码addMatrices使用与原始MATLAB代码相同的二维索引。您可以轻松地将生成的代码与原始算法进行比较。要了解如何使用行-主布局,请参见生成使用行-主数组布局的代码

列主布局和n维索引

数组布局的选择影响n维索引的外观。例如,为addMatrices函数使用列主数组布局:

cfg。RowMajor = false;codegenaddMatricesarg游戏{的(2、4)的(2、4)}配置cfg-launchreport

代码生成生成以下C代码:

/* N-d索引on, row-major off */ void addMatrices(double A[4][2], double B[4][2], double sum[4][2]) {int row;int上校;For (row = 0;行< 2;Row ++) {for (col = 0;Col < 4;坳+ +){总和(col)(行)= (col)(行)+ B (col)(行);}}}

C代码中的输入和输出矩阵是原始MATLAB矩阵的转置。要理解其中的原因,请考虑数组在计算机内存中是如何表示的。MATLAB语言默认使用列主布局,其中第一个(最左)维度或索引的元素在内存中是连续的。C默认使用行主数组布局,其中来自最后(最右边)维度或索引的元素是连续的。为了保持原始的元素邻接关系,代码生成器必须反转数组维度的顺序。

例如,在这种情况下,如果你定义MATLAB矩阵一个为:

=重塑(1:8,2、4)

A = 1 3 5 7 2 4 6 8

然后,由于MATLAB使用列-主布局,数据在内部按顺序存储:

A(:)' = 1 2 3 4 5 6 7 8

在C代码中,您必须对原始数据进行转置,对于本例,调用它AA

Aa = {{1,2}, {3,4}, {5,6}, {7,8};

获取具有相同内部存储顺序的数据元素列表。换句话说,C数组必须是4 × 2的。(通过将数组定义为2 × 4的数组,可以获得等效的存储顺序Aa = {{1,2,3,4}, {5,6,7,8}}.然而,获取这个顺序需要手动重塑或重新排列数据。)

数组布局的选择只影响内部数据表示,不会改变计算或算法结果。为了在生成的代码中保持MATLAB数组的直观外观,使用n维索引和行主数组布局。注意,行主布局会影响生成代码的效率。有关更多信息,请参见行-主阵列布局的代码设计

其他代码生成注意事项

考虑n维索引的其他方面。代码生成器总是为n维向量生成一维数组,即使在指定n维索引时也是如此。例如,如果你为MATLAB矢量生成代码:

A = 0 (1,10)

A = 0 (1,10,1)

生成的C/ c++数组存储为:

一个[10]

n维索引也适用于数组和结构。例如,如果你在代码中声明结构为:

X = struct(“f1”的(2、3));coder.cstructname (x,“myStruct1”);Y = struct(“f2”的(6,1));coder.cstructname (y,“myStruct2”);

然后生成的代码包含结构定义:

Typedef结构{双f1[2][3];} myStruct1;Typedef结构{double f2[6];} myStruct2;

避免在n维数组上进行线性索引。例如,当你使用冒号操作符时,会发生线性索引:

(:)

要应用线性索引,代码生成器必须将n维数组转换为一维数组。强制转换操作使代码生成器分析起来更加复杂。这种增加的复杂性可能会阻碍代码生成器优化性能的能力。

最后,注意以下几点:

  • 可以对任何数据类型的数组使用n维索引。

  • 只有固定大小的数组,而不是可变大小的数组,可以使用n维索引。

另请参阅

||

相关的话题

Baidu
map