主要内容

生成使用n维索引的代码

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

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

MATLAB代码

生成的C代码(默认)

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

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);行= 1:大小(A,1)(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

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

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(双A[4][2],双B[4][2],双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”);

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

类型定义结构{双f1[2][3];} myStruct1;Typedef struct {double f2[6];} myStruct2;

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

(:)

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

最后,请注意以下几点:

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

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

另请参阅

||

相关的话题