Inlining is an optimization technique that replaces a function call with the contents (body) of that function. Inlining eliminates the overhead of a function call, thereby improving speed.
Depending on your application, too much code inlining can also have certain disadvantages:
Inlining can produce larger C/C++ code and reduce code readability. For
example, suppose that you call a certain function foo
many
times in your source MATLAB® code. If the code generator
always inlines foo
, the
generated code size increases because foo
is inlined every
time it is called. However, for this to happen, the call sites must be
different. For example, inlining does not lead to large code size if
foo
is called several times inside a loop.
For out-of-line functions, stack space for variables local to the function is released when the function returns. For inlined functions, stack space remains occupied by the local variables even when the function returns. So, if you have limited RAM or stack space, you might want to restrict function inlining.
The code generator uses internal heuristics to determine whether to inline functions in the generated code. This help topic explains how to fine-tune these heuristics and generate code that meets the speed, readability, and stack space requirements of your application.
To instruct the code generator to either always
or never inline a certain MATLAB function, use the coder.inline('always')
and
coder.inline('never')
directives inside the body of that
function. To learn more about these directives, see coder.inline
.
You might have different speed and readability requirements for the code generated for functions that you write and the code generated for MathWorks® functions. Certain code generation settings enable you to separately control the inlining behavior for these two parts of the generated code base and at the boundary between them. These settings apply to both MEX and standalone code generation.
Code Configuration Parameter | Description | Options |
---|---|---|
In a code configuration object:
In the MATLAB Coder™ app: On the All Settings tab, Inline between user functions | Controls inlining behavior at all call sites where a function that you wrote calls another function that you wrote | 'Always' | 'Speed'
(default) | 'Readability' |
'Never' |
In a code configuration object:
In the MATLAB Coder app: On the All Settings tab, Inline between MathWorks functions | Controls inlining behavior at all call sites where a MathWorks function calls another MathWorks function | 'Always' | 'Speed'
(default) | 'Readability' |
'Never' |
In a code configuration object:
In the MATLAB Coder app: On the All Settings tab, Inline between user and MathWorks functions | Controls inlining behavior at all call sites where a function that you wrote calls a MathWorks function, or a MathWorks function calls a function that you wrote | 'Always' | 'Speed'
(default) | 'Readability' |
'Never' |
Option descriptions:
'Always'
: Always
performs inlining at a call site.
'Speed'
: Uses internal heuristics to determine whether
to perform inlining at a call site. This setting usually leads to highly
optimized code. This setting is the default setting.
'Readability'
: Almost
never inlines function calls, except for
calls to very small functions. Preserves modularity of code without
sacrificing too much speed, whenever
possible. Results in highly readable
code.
'Never'
: Never
inlines function calls. Results in maximum readability. This setting might
significantly reduce the performance of
the generated code.
Note
In certain cases, the code generator might not strictly follow the option you
choose for an inlining parameter. For example, if the body of a MathWorks function contains the coder.inline('never')
directive and you set InlineBetweenMathWorksFunctions
to
'Always'
, the code generator gives preference to the
coder.inline
directive and does not inline that function.
For more information, see Interaction Between Different Inlining Controls.
This is an example inlining strategy that balances the speed and readability of the generated code. You instruct the code generator to perform these actions simultaneously:
Preserve the modularity in the code that you write for better
readability, even if that reduces the speed of the generated code. For
this behavior, set InlineBetweenUserFunctions
to
'Readability'
.
Generate highly optimized code for MathWorks functions, even if that results in less readable code
because you are less likely to inspect this part of your code base. For
this behavior, set InlineBetweenMathWorksFunctions
to
'Speed'
.
In the generated code, separate functions that you write and
MathWorks functions so that the generated code does not look very
different from your MATLAB code. For this behavior, set
InlineBetweenUserAndMathWorksFunctions
to
'Readability'
.
The coder.inline('always')
or
coder.inline('never')
directive placed inside the
body of a MATLAB function overrides the
effect of the global inlining controls,
including the codegen
options and the code configuration
settings. See coder.inline
.
Certain MathWorks functions include a call to the
coder.inline
directive that affects how those
functions interact with the global inlining settings. For example, if the
body of a MathWorks function contains the coder.inline('never')
directive and you set InlineBetweenMathWorksFunctions
to
'Always'
, the code generator gives preference to the
coder.inline
directive and does not inline that
function.
The -O disable:inline
and -O
enable:inline
options of the codegen
command override the
individual values of the three code configuration parameters
InlineBetweenUserFunctions
,
InlineBetweenMathWorksFunctions
, and
InlineBetweenUserAndMathWorksFunctions
.
This example shows how to control inlining behavior at all call sites where a function that you wrote calls a MathWorks function, or a MathWorks function calls a function that you wrote.
Define A Function That Calls MathWorks Functions
Define a MATLAB function useBessely
that accepts a double array x
as input, processes the input array by using the bessely
function, and returns an array that has the same type and size as x
.
type useBessely.m
function out = useBessely(x) out = x + bessely(3,x); end
Generate Code With Default Inlining Settings
Generate a static C++ library for the useBessely
function. Specify the input to be a 1
-by-100
double
type. Use the default values for the inlining settings. These default values optimize the speed of the generated code. Use the -c
flag that instructs the code generator to produce source code only and not build the source code.
codegen -c -lang:c++ -config:lib useBessely -args {zeros(1,100)} -report
Code generation successful: To view the report, open('codegen/lib/useBessely/html/report.mldatx').
Open the code generation report and inspect the generated code. Observe that no separate C++ function has been generated for the MathWorks function bessely
. The code generator has inlined the code for the bessely
function into the C++ useBessely
function that is contained in the file useBessely.cpp
.
Generate Code With Modified Inlining Settings
Define a code configuration object cfg
for generating a static C++ library. Set the property InlineBetweenUserAndMathWorksFunctions
to 'Never'
. This setting instructs the code generator to separate the function that you wrote and the MathWorks functions in the generated code. As a result, the generated C++ code is less efficient but more readable than the inlined code.
cfg = coder.config('lib'); cfg.TargetLang = 'C++'; cfg.InlineBetweenUserAndMathWorksFunctions = 'Never';
Generate code by using cfg
as the code configuration object. Specify the input to be a 1
-by-100
double
type. Use the -c
flag that instructs the code generator to produce source code only and not build the source code.
codegen -c -config cfg useBessely -args {zeros(1,100)} -report
Code generation successful: To view the report, open('codegen/lib/useBessely/html/report.mldatx').
Open the code generation report and inspect the generated code. The C++ function useBessely
now calls another C++ function coder::bessely
that contains the code generated for the MathWorks function bessely
. As a reault, the generated C++ useBessely
function looks similar to the MATLAB useBessely
function that you wrote.
type codegen/lib/useBessely/useBessely.cpp
// // File: useBessely.cpp // // MATLAB Coder version : 5.1 // C/C++ source code generated on : 17-Aug-2020 20:28:16 // // Include Files #include "useBessely.h" #include "bessely.h" #include "rt_nonfinite.h" // Function Definitions // // Arguments : const double x[100] // creal_T out[100] // Return Type : void // void useBessely(const double x[100], creal_T out[100]) { coder::bessely(x, out); for (int i = 0; i < 100; i++) { out[i].re += x[i]; } } // // File trailer for useBessely.cpp // // [EOF] //
codegen
| coder.CodeConfig
| coder.EmbeddedCodeConfig
| coder.inline
| coder.MexCodeConfig