coder.inline
控制生成代码中当前函数的内联
说明
coder.inline("always")
在生成代码中内联当前函数(coder.inline
所在的函数)。使用 coder.inline("always")
优化指令将函数调用替换为被调函数的函数体。内联消除了函数调用的开销,并为进一步优化生成的 C/C++ 代码提供了机会。但是,内联可能生成更庞大、更复杂的 C/C++ 代码。
coder.inline("always")
指令不支持以下项的内联:
入口函数
递归函数
包含
parfor
循环的函数从
parfor
循环中调用的函数
coder.inline("never")
可阻止在生成的代码中内联使用它的函数。当您要简化 MATLAB® 源代码和生成代码之间的映射时,请使用 coder.inline("never")
优化指令。
coder.inline("never")
指令不会阻止以下项的内联:
空函数
返回常量输出的函数
若要即使在这些情况下也防止内联,请在 MATLAB 代码中的函数调用点对输入使用 coder.ignoreConst
函数。有关详细信息,请参阅Resolve Issue: coder.inline("never") and coder.nonInlineCall Do Not Prevent Function Inlining。
coder.inline("default")
指示代码生成器使用内部启发式方法来确定是否内联当前函数。通常,这些启发式方法会产生高度优化的代码。
示例
控制函数内联
创建一个入口函数 inliningEntryPoint
,该函数调用两个局部函数 local_Inline
和 local_NoInline
。这两个局部函数都返回输入值的平方,但 local_Inline
使用指令 coder.inline("always")
,而 local_NoInline
使用指令 coder.inline("never")
。
type inliningEntryPoint.m
function [x,y] = inliningEntryPoint(n) %#codegen arguments n (1,1) double end x = local_Inline(n); y = local_NoInline(n); end function y = local_Inline(x) coder.inline("always"); y = x^2; end function y = local_NoInline(x) coder.inline("never"); y = x^2; end
为 inliningEntryPoint
生成 C 代码,并检查生成代码中的入口函数。代码生成器会内联对 local_Inline
的调用,但不内联对 local_NoInline
的调用。
codegen -config:lib inliningEntryPoint
Warning: Code generation is using a coder.EmbeddedCodeConfig object. Because Embedded Coder is not installed, this might cause some Embedded Coder features to fail. Code generation successful (with warnings): To view the report, open('codegen/lib/inliningEntryPoint/html/report.mldatx')
type(fullfile("codegen","lib","inliningEntryPoint","inliningEntryPoint.c"))
/* * File: inliningEntryPoint.c * * MATLAB Coder version : 24.1 * C/C++ source code generated on : 20-Apr-2024 06:06:37 */ /* Include Files */ #include "inliningEntryPoint.h" /* Function Declarations */ static double local_NoInline(double x); /* Function Definitions */ /* * Arguments : double x * Return Type : double */ static double local_NoInline(double x) { return x * x; } /* * Arguments : double n * double *x * double *y * Return Type : void */ void inliningEntryPoint(double n, double *x, double *y) { *x = n * n; *y = local_NoInline(n); } /* * File trailer for inliningEntryPoint.c * * [EOF] */
在流控制语句中使用 coder.inline
您可以使用多个 coder.inline
指令根据输入参量等参数来控制函数内联。
创建入口函数 conditionalInlining
,该函数调用局部函数 simpleDivision
。仅当两个输入参量均为标量时,才使用多个 coder.inline
指令指示代码生成器内联 simpleDivision
。
type conditionalInlining.m
function out = conditionalInlining(x,y) %#codegen out = simpleDivision(x,y); end function y = simpleDivision(dividend, divisor) if isscalar(dividend) && isscalar(divisor) forceInlining = "always"; else forceInlining = "default"; end coder.inline(forceInlining) y = dividend / divisor; end
为 conditionalInlining
生成 C 代码,指定标量输入,并在生成代码中检查入口函数。代码生成器在生成代码中内联 simpleDivision
。
codegen -config:lib conditionalInlining -args {3 4}
Warning: Code generation is using a coder.EmbeddedCodeConfig object. Because Embedded Coder is not installed, this might cause some Embedded Coder features to fail. Code generation successful (with warnings): To view the report, open('codegen/lib/conditionalInlining/html/report.mldatx')
type(fullfile("codegen","lib","conditionalInlining","conditionalInlining.c"))
/* * File: conditionalInlining.c * * MATLAB Coder version : 24.1 * C/C++ source code generated on : 20-Apr-2024 06:07:41 */ /* Include Files */ #include "conditionalInlining.h" /* Function Definitions */ /* * Arguments : double x * double y * Return Type : double */ double conditionalInlining(double x, double y) { return x / y; } /* * File trailer for conditionalInlining.c * * [EOF] */
为 conditionalInlining
生成 C 代码,指定向量输入,并在生成代码中检查入口函数。代码生成器使用内部启发式方法来确定是否在生成代码中内联 simpleDivision
。
codegen -config:lib conditionalInlining -args {1:10 11:20}
Warning: Code generation is using a coder.EmbeddedCodeConfig object. Because Embedded Coder is not installed, this might cause some Embedded Coder features to fail. Code generation successful (with warnings): To view the report, open('codegen/lib/conditionalInlining/html/report.mldatx')
type(fullfile("codegen","lib","conditionalInlining","conditionalInlining.c"))
/* * File: conditionalInlining.c * * MATLAB Coder version : 24.1 * C/C++ source code generated on : 20-Apr-2024 06:07:45 */ /* Include Files */ #include "conditionalInlining.h" #include "rt_nonfinite.h" #include "xnrm2.h" #include "rt_nonfinite.h" #include <emmintrin.h> #include <math.h> #include <string.h> /* Function Declarations */ static double rt_hypotd_snf(double u0, double u1); /* Function Definitions */ /* * Arguments : double u0 * double u1 * Return Type : double */ static double rt_hypotd_snf(double u0, double u1) { double a; double b; double y; a = fabs(u0); b = fabs(u1); if (a < b) { a /= b; y = b * sqrt(a * a + 1.0); } else if (a > b) { b /= a; y = a * sqrt(b * b + 1.0); } else if (rtIsNaN(b)) { y = rtNaN; } else { y = a * 1.4142135623730951; } return y; } /* * Arguments : const double x[10] * const double y[10] * Return Type : double */ double conditionalInlining(const double x[10], const double y[10]) { __m128d r; __m128d r1; double A[10]; double B[10]; double out; double tau; double wj; int i; int knt; int rankA; memcpy(&A[0], &y[0], 10U * sizeof(double)); memcpy(&B[0], &x[0], 10U * sizeof(double)); tau = 0.0; for (i = 0; i < 1; i++) { double atmp; atmp = A[0]; tau = 0.0; wj = xnrm2(A); if (wj != 0.0) { double beta1; beta1 = rt_hypotd_snf(A[0], wj); if (A[0] >= 0.0) { beta1 = -beta1; } if (fabs(beta1) < 1.0020841800044864E-292) { knt = 0; do { knt++; r = _mm_loadu_pd(&A[1]); r1 = _mm_set1_pd(9.9792015476736E+291); _mm_storeu_pd(&A[1], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[3]); _mm_storeu_pd(&A[3], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[5]); _mm_storeu_pd(&A[5], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[7]); _mm_storeu_pd(&A[7], _mm_mul_pd(r1, r)); A[9] *= 9.9792015476736E+291; beta1 *= 9.9792015476736E+291; atmp *= 9.9792015476736E+291; } while ((fabs(beta1) < 1.0020841800044864E-292) && (knt < 20)); beta1 = rt_hypotd_snf(atmp, xnrm2(A)); if (atmp >= 0.0) { beta1 = -beta1; } tau = (beta1 - atmp) / beta1; wj = 1.0 / (atmp - beta1); r = _mm_loadu_pd(&A[1]); r1 = _mm_set1_pd(wj); _mm_storeu_pd(&A[1], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[3]); _mm_storeu_pd(&A[3], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[5]); _mm_storeu_pd(&A[5], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[7]); _mm_storeu_pd(&A[7], _mm_mul_pd(r1, r)); A[9] *= wj; for (rankA = 0; rankA < knt; rankA++) { beta1 *= 1.0020841800044864E-292; } atmp = beta1; } else { tau = (beta1 - A[0]) / beta1; wj = 1.0 / (A[0] - beta1); r = _mm_loadu_pd(&A[1]); r1 = _mm_set1_pd(wj); _mm_storeu_pd(&A[1], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[3]); _mm_storeu_pd(&A[3], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[5]); _mm_storeu_pd(&A[5], _mm_mul_pd(r1, r)); r = _mm_loadu_pd(&A[7]); _mm_storeu_pd(&A[7], _mm_mul_pd(r1, r)); A[9] *= wj; atmp = beta1; } } A[0] = atmp; } rankA = 0; wj = fabs(A[0]); if (!(wj <= 2.2204460492503131E-14 * wj)) { rankA = 1; } out = 0.0; if (tau != 0.0) { wj = x[0]; for (i = 0; i < 9; i++) { wj += A[i + 1] * x[i + 1]; } wj *= tau; if (wj != 0.0) { __m128d r2; B[0] = x[0] - wj; r = _mm_loadu_pd(&A[1]); r1 = _mm_loadu_pd(&B[1]); r2 = _mm_set1_pd(wj); _mm_storeu_pd(&B[1], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); r = _mm_loadu_pd(&A[3]); r1 = _mm_loadu_pd(&B[3]); _mm_storeu_pd(&B[3], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); r = _mm_loadu_pd(&A[5]); r1 = _mm_loadu_pd(&B[5]); _mm_storeu_pd(&B[5], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); r = _mm_loadu_pd(&A[7]); r1 = _mm_loadu_pd(&B[7]); _mm_storeu_pd(&B[7], _mm_sub_pd(r1, _mm_mul_pd(r, r2))); } } for (i = 0; i < rankA; i++) { out = B[0]; } for (knt = rankA; knt >= 1; knt--) { out /= A[0]; } return out; } /* * File trailer for conditionalInlining.c * * [EOF] */
提示
如果使用
codegen
或fiaccel
(Fixed-Point Designer) 命令,则可以使用-O disable:inline
选项对所有函数禁用内联。与从 MathWorks® 函数生成的 C/C++ 代码相比,从您编写的函数生成的 C/C++ 代码可能有不同速度和可读性要求。附加的全局设置使您能够控制生成的代码库的这两部分的内联。请参阅Control Inlining to Fine-Tune Performance and Readability of Generated Code。
扩展功能
C/C++ 代码生成
使用 MATLAB® Coder™ 生成 C 代码和 C++ 代码。
GPU 代码生成
使用 GPU Coder™ 为 NVIDIA® GPU 生成 CUDA® 代码。
HDL 代码生成
使用 HDL Coder™ 为 FPGA 和 ASIC 设计生成 VHDL、Verilog 和 SystemVerilog 代码。
coder.inline
函数支持 MATLAB 到高级综合代码生成。
版本历史记录
在 R2011a 中推出
MATLAB 命令
您点击的链接对应于以下 MATLAB 命令:
请在 MATLAB 命令行窗口中直接输入以执行命令。Web 浏览器不支持 MATLAB 命令。
Select a Web Site
Choose a web site to get translated content where available and see local events and offers. Based on your location, we recommend that you select: .
You can also select a web site from the following list:
How to Get Best Site Performance
Select the China site (in Chinese or English) for best site performance. Other MathWorks country sites are not optimized for visits from your location.
Americas
- América Latina (Español)
- Canada (English)
- United States (English)
Europe
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)