主要内容

生成使用n维索引的代码

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

该表展示了使用和不使用n维索引时生成的代码的差异。

MATLAB代码

生成的C代码(默认)

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

A =零(2,4,6)
A [48]
  • 使用列-主数组布局(默认):

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

    a [2] [4] [6]

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

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

启用n维索引:

  • 使用-preserveArraydims.选择:

    Codegen.Foo-preserveArraydims.
  • 设定PreserveArrayDimensions.您的代码生成配置对象的属性真正的。例如:

    cfg = coder.config('lib');cfg.preserveArraydimensions = true;Codegen.Foo-Config.CFG.

的n维索引Matlab Coder™应用程序:

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

  • 打开产生单击对话框产生箭头

  • 点击更多设置

  • 在这一点记忆选项卡中,选择保留阵列尺寸复选框。

提高N维索引和行主要布局的可读性

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

考虑MATLAB函数addMatrices,它添加两个矩阵,按元素元素:

函数和= addMatrices (A, B)%#codegen.和= coder.nullcopy(一个);为了行= 1:尺寸(a,1)为了sum(row,col) = A(row,col) + B(row,col);结尾结尾

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

cfg = coder.config('lib');cfg.preserveArraydimensions = true;cfg.rowmajor = true;Codegen.addMatrices-  args.{ONE(2,4),那些(2,4)}-Config.CFG.-launchreport.

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

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;坳< 4;坳+ +){总和(行)(col) =(行)(col) + B(行)(col);}}}

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

列 - 主要布局和N维索索引

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

cfg。RowMajor = false;Codegen.addMatrices-  args.{ONE(2,4),那些(2,4)}-Config.CFG.-launchreport.

代码生成该C代码:

/ * N-D索引ON,行 - 主偏压* / void addMatrices(Double A [4] [2],双B [4] [2],Double Sum [4] [2]){int行;int上校;for(行= 0;行<2;行++){for(col = 0; col <4; col ++){sum [col] [行] = a [col] [行] [col] [行];}}}

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

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

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

a = 1 3 5 7 2 4 6 8

然后,由于MATLAB使用column-major布局,数据在内部存储的顺序是:

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

在C代码中,必须转换原始数据,例如,调用它AA.

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

使用相同的内部存储顺序达到数据元素列表。换句话说,C阵列必须是4-of-2。(使用以下方法将数组定义为2×4,可以获得等效存储顺序aa = {{{{{1,2,3,4},{5,6,7,8}}。但是,获取此订单需要手动重塑或重新排列数据。)

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

其他代码生成注意事项

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

= 0 (10)

a =零(1,10,1)

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

a [10]

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

x = struct(“f1”的(2、3));coder.cstructname (x,'mystruct1');y =结构(“f2”,一个(1,6,1));Coder.cstructName(y,'mystruct2');

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

typedef结构{double f1 [2] [3];mystruct1;typedef struct {double f2 [6];mystruct2;

避免在N维数组上线性索引。例如,当您使用冒号运算符时,发生线性索引:

(:)

要应用线性索引,代码生成器必须将n维数组转换为一维数组。铸造操作使您的代码更复杂的代码生成器进行分析。这种增加的复杂性可以阻碍代码发生器优化性能的能力。

最后,注意以下几点:

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

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

也可以看看

||

相关的话题