主要内容

为可变大小的数据生成代码

可变大小数据是指其大小在运行时可能改变的数据。您可以使用MATLAB®编码器™从MATLAB代码生成C/ c++代码,使用可变大小的数据。MATLAB支万博1manbetx持有界和无界变量大小的数据用于代码生成。有界可变大小数据有固定的上界。这个数据可以在堆栈上静态分配,也可以在堆上动态分配。无界适应数据没有固定的上界。这个数据必须分配到堆上。默认情况下,对于MEX和C/ c++代码生成,启用了对可变大小数据的支持,并为大小大于或等于可万博1manbetx配置阈值的可变大小数组启用了动态内存分配。

禁用支持可变大小万博1manbetx数据

默认情况下,对于MEX和C/ c++代码生成,启用了对可变大小数据的支持。万博1manbetx您可以从项目设置对话框、命令行或使用对话框中修改可变大小设置。

使用MATLAB编码员应用程序

  1. 打开生成对话框,位于生成代码页面,点击生成箭头

  2. 点击更多的设置

  3. 内存选项卡,选择或清除启用可变大小

在命令行

  1. 创建用于代码生成的配置对象。例如,对于库:

    cfg = coder.config(“自由”);

  2. 设定启用可变大小选项:

    cfg。EnableVariableSizing = false;

  3. 使用配置选项,将配置对象传递给codegen

    codegen-config cfg foo

控制动态内存分配

默认情况下,对大小大于或等于可配置阈值的可变大小数组启用动态内存分配。如果您禁用了对可变大小数据的支万博1manbetx持(参见禁用支持可变大小万博1manbetx数据),您还可以禁用动态内存分配。可以从“项目设置”对话框或命令行修改动态内存分配设置。

使用MATLAB编码员应用程序

  1. 打开生成对话框,位于生成代码页面,点击生成箭头

  2. 点击更多的设置

  3. 内存选项卡,设置动态内存分配选择下列选项之一:

    背景 行动
    从来没有 禁用动态内存分配。可变大小的数据是在堆栈上静态分配的。
    对于所有可变大小的阵列 为可变大小的数组启用了动态内存分配。在堆上动态分配大小可变的数据。
    对于最大大小等于或高于阈值的阵列 的大小为可变大小的数组启用动态内存分配动态内存分配阈值.在堆栈上分配大小小于此阈值的可变大小数组。

  4. 如果你设置动态内存分配对于最大大小大于或等于阈值的数组,配置动态内存分配阈值调整内存分配。

在命令行

  1. 创建用于代码生成的配置对象。例如,对于MEX函数:

    mexcfg = coder.config(墨西哥人);

  2. 设定动态内存分配选项:

    背景 行动
    mexcfg.DynamicMemoryAllocation =“关闭”;
    禁用动态内存分配。可变大小的数据是在堆栈上静态分配的。
    mexcfg.DynamicMemoryAllocation =“AllVariableSizeArrays”;
    为可变大小的数组启用了动态内存分配。在堆上动态分配大小可变的数据。
    mexcfg.DynamicMemoryAllocation =“阈值”;
    属性指定的大小(以字节为单位)大于或等于可变大小数组的值时,将启用动态内存分配DynamicMemoryAllocationThreshold参数。在堆栈上分配大小小于此阈值的可变大小数组。

  3. 如果你设置动态内存分配“阈值”,配置DynamicMemoryAllocationThreshold微调内存分配。

  4. 使用配置选项,将配置对象传递给codegen

    Codegen -config mexcfg foo

生成的代码MATLAB具有可变大小数据的函数

下面是一个基本的工作流,它首先生成MEX代码以验证生成的代码,然后在您对原型的结果感到满意后生成独立的代码。

要通过一个简单的示例完成这些步骤,请参见为循环中展开向量的MATLAB函数生成代码

  1. 在MATLAB编辑器中,添加编译指令% # codegen在你的功能的顶端。

    这个指令:

    • 表示您打算为MATLAB算法生成代码

    • 打开MATLAB代码分析器中的检查,以检测代码生成期间的潜在错误

  2. 解决代码分析器检测到的问题。

    在某些情况下,当代码为数据指定了固定大小,但随后又增加了数据时(例如通过循环中的指定或串联),MATLAB代码分析器会发出警告。如果该数据在运行时大小不同,则可以忽略这些警告。

  3. 使用codegen以验证生成的代码。使用以下命令行选项:

    • args {coder.typeof…}如果你有可变大小的输入

    • -报告生成代码生成报告的步骤

    例如:

    Codegen -report foo -args{编码器。typeof (0, 2 [4], 1)}
    此命令使用coder.typeof为函数指定一个可变大小输入的步骤喷火. 第一个论点,,0,表示输入数据类型(双重的)和复杂性(真正的).第二个参数,(2 - 4),表示大小,一个二维矩阵。第三个参数,1,表示输入是可变大小的。第一维的上限是2,第二维的上限是4。

    请注意

    在编译过程中,codegen检测在定义变量和结构字段后大小发生变化的变量和结构字段,并将这些情况报告为错误。此外,codegen当数据超过上限时,执行运行时检查以生成错误。

  4. 修复尺寸不匹配错误:

    原因 如何修复 的更多信息
    锁定数据大小后,尝试更改其大小。 声明数据为可变大小。 看到诊断和修复大小不匹配错误
  5. 修正上界错误

    原因 如何修复 的更多信息
    MATLAB无法确定或计算上限 请指定上限。 看到指定可变大小数组的上界诊断和修复大小不匹配错误
    MATLAB试图计算无界可变大小数据的上限。 如果数据是无界的,请启用动态内存分配。 看到控制动态内存分配
  6. 生成C/ c++代码使用codegen函数。

为一个应用程序生成代码MATLAB在循环中展开向量的函数

关于MATLAB功能性肌醇

此示例使用函数米尼克托.这个函数以vector形式返回B输入向量的一个版本一个,其中元素在公差范围内是唯一的托尔彼此的。在向量B腹肌B)- - -Bj)) >托尔对所有j.首先,假设输入向量一个可存储多达100个元素。

函数B=myuniquetol(A,tol)A=sort(A);B=A(1);k=1;我= 2:长度(A)如果abs(A(k) - A(i)) > tol B = [B A(i)];k =我;结束结束

步骤1:为代码生成添加编译指令

添加% # codegen函数顶部的编译指令:

函数B = myuniquetol(A, tol)% # codegen一种=(一个);B = (1);k = 1;我= 2:长度(A)如果abs(A(k) - A(i)) > tol B = [B A(i)];k =我;结束结束

步骤2:处理代码分析器检测到的问题

代码分析器检测该变量B可能会改变大小对- - - - - -环它发出以下警告:

变量'B'似乎在每次循环迭代时都会改变大小。考虑提前分配。

在这个函数中,你期望向量B扩展大小,因为它从向量中添加值一个。因此,您可以忽略此警告。

步骤3:生成MEX代码

最佳做法是在生成C/C++代码之前生成MEX代码。生成MEX代码可以识别在运行时更难检测的代码生成问题。

  1. 为生成一个MEX函数米尼克托

    Codegen -report myuniquetol -args{编码器。typeof (0, [100], 1), coder.typeof (0)}

    这些命令行选项意味着什么?

    代码生成成功。codegen不检测问题。在当前文件夹中,codegen为生成一个MEX函数米尼克托并提供到代码生成报告的链接。

  2. 点击查看报告链接。

  3. 在“代码生成”报告中,选择变量标签。

    的大小一个1 x: 100因为你指定了一个是上限为的可变大小One hundred..变量的大小B1x:?,表示它是没有上限的可变大小。

步骤4:生成C代码

为可变大小的输入生成C代码。默认情况下,codegen为小于动态内存分配阈值64kb的数据静态分配内存。如果数据的大小大于或等于阈值或无边界,codegen在堆上动态分配内存。

  1. 为C库生成创建一个配置选项:

    cfg = coder.config(“自由”);
  2. 发出此命令:

    Codegen -config CFG -report myuniquetol -args{编码器。typeof (0, [100], 1), coder.typeof (0)}

    codegen在默认位置生成静态库,codegen \ lib \ myuniquetol并提供到代码生成报告的链接。

  3. 点击查看报告链接。

  4. 在生成的文件列表中,单击米尼克托

    函数声明是:

    extern void myuniquetol(const double A_data[], const int A_size[2], double tol, emxArray_real_T *B);

    codegen计算对象的大小一个而且,因为它的最大大小小于默认的动态内存分配阈值64k字节,所以静态分配该内存。生成的代码包含:

    • 双A_data []:定义一个

    • int A_size [2]:输入的实际大小。

    代码生成器确定B具有未知上界的可变大小。它代表了B作为emxArray_real_T.MATLAB提供了用于创建和交互的实用函数emxArrays在您生成的代码中。有关更多信息,请参见在生成的函数接口中使用C数组

步骤5:指定输出向量的上限

您指定输入一个是上限为的可变大小One hundred.. 因此,您知道输出B不能大于One hundred.元素。

  • 使用变码器表明B是上限为的可变大小One hundred.

    函数B = myuniquetol(A, tol) %#codegen A = sort(A);变码器('B', [1 100], [0 1]); B = A(1); k = 1; for i = 2:length(A) if abs(A(k) - A(i)) > tol B = [B A(i)]; k = i; end end

  • 生成代码。

    Codegen -config CFG -report myuniquetol -args{编码器。typeof (0, [100], 1), coder.typeof (0)}

    函数声明是:

    外部无效myuniquetol(常数双A_数据[],常数内A_大小[2],双tol,双B_数据[],内B_大小[2]);

    代码生成器静态地为以下对象分配内存B.它存储的大小Bint B_size [2]

步骤6:更改动态内存分配阈值

在这一步中,您将降低动态内存分配阈值,并为超过该阈值的输入生成代码。此步骤指定的第二个维度一个的上界是10000

  1. 改变的上界B的上界一个

    函数B = myuniquetol(A, tol) %#codegen A = sort(A);变码器('B', [1 10000], [0 1]); B = A(1); k = 1; for i = 2:length(A) if abs(A(k) - A(i)) > tol B = [B A(i)]; k = i; end end

  2. 将动态内存分配阈值设置为4 KB,并生成输入大小为一个超过这个阈值。

    cfg.DynamicMemoryAllocationThreshold = 4096;Codegen -config CFG -report myuniquetol -args{编码器。typeof (0, [10000], 1), coder.typeof (0)}

  3. 在报告中查看生成的代码。因为最大的尺寸一个B现在超过了动态内存分配阈值,codegen分配一个B动态地在堆上。在生成的代码中,一个B有类型emxArray_real_T

    外部无效myuniquetol(常数emxArray_real_T*A、双tol、emxArray_real_T*B);

相关的话题