Optimize Generated Code with the Model Advisor
You can use the Simulink® Model Advisor to help you configure your fixed-point models to achieve a more efficient design and optimize your generated code. To use the Model Advisor to check your fixed-point models:
In the Modeling tab of the model you want to analyze, click Model Advisor.
In the System Selector, select the system to analyze.
In the Model Advisor left pane, expand the By Product node and then the Embedded Coder node.
For fixed-point code generation, the most important check boxes to select are Identify blocks that generate expensive fixed-point and saturation code, Identify questionable fixed-point operations, Identify blocks that generate expensive rounding code, and Check the hardware implementation.
To enable all Model Advisor checks associated with the selected node, select the check box of the folder containing the checks. In our case, select the Embedded Coder check box.
Click Run checks. Any tips for improving the efficiency of your fixed-point model appear in the Model Advisor window.
The sections that follow discuss fixed-point related checks and sub-checks found in the Model Advisor. These sections explain the checks, discuss their importance in fixed-point code generation, and offer suggestions for tweaking your model to optimize your generated code.
Identify Blocks That Generate Expensive Fixed-Point and Saturation Code
Identify Sum blocks for questionable fixed-point operations
When the input range of a Sum block exceeds the output range, a range error occurs. You can get any addition or subtraction your application requires by inserting data type conversion blocks before and/or after the Sum block.
When a Sum block has an input with a slope adjustment factor that does not equal the slope adjustment factor of the output, the mismatch requires the Sum block to perform a multiply operation each time the input is converted to the data type and scaling of the output. The mismatch can be removed by changing the scaling of the output or the input.
When the net sum of the Sum block input biases does not equal the bias of the output, the generated code includes one extra addition or subtraction instruction to correctly account for the net bias adjustment. Changing the bias of the output scaling can make the net bias adjustment zero and eliminate the need for the extra operation.
Identify Min Max blocks for questionable fixed-point operations
When the input and output of the MinMax block have different data types, a conversion operation is required every time the block is executed. The model is more efficient with the same data types.
When the data type and scaling of the input of the MinMax block does not match the data type and scaling of the output, a conversion is required before performing a relational operation. This could result in a range error when casting, or a precision loss each time a conversion is performed. Change the scaling of either the input or output to generate more efficient code.
When the input of the MinMax block has a different slope adjustment factor than the output, the MinMax block requires a multiply operation each time the block is executed to convert the input to the data type and scaling of the output. You can correct the mismatch by changing the scaling of either the input or output.
Identify Discrete Integrator blocks for questionable fixed-point operations
When the initial condition for the Discrete-Time Integrator blocks is used to initialize the state and output, the output equation generates excessive code and an extra global variable is required. It is recommended that you set the Function Block Parameters > Initial condition setting parameter to
State (most efficient)
.
Identify Compare to Constant blocks for questionable fixed-point operations
If the input data type of the Compare to Zero block cannot represent zero exactly, the input signal is compared to the closest representable value of zero, resulting in parameter overflow. To avoid this parameter overflow, select an input data type that can represent zero.
If the Constant value parameter of the Compare to Constant is outside the range that the input data type can represent, the input signal is compared to the closest representable value of the constant. This results in parameter overflow. To avoid this parameter overflow, select an input data type that can represent the Constant value, or change the Constant value to a value that can be accommodated by the input data type.
Identify Lookup Table blocks for questionable fixed-point operations
Efficiency trade-offs related to lookup table data are described in Effects of Spacing on Speed, Error, and Memory Usage. Based on these trade-offs, the Model Advisor identifies blocks where there is potential for efficiency improvements, such as:
Lookup table input data is not evenly spaced.
Lookup table input data is not evenly spaced when quantized, but it is very close to being evenly spaced.
Lookup table input data is evenly spaced, but the spacing is not a power of two.
For more information on lookup table optimization, see Lookup Table Optimization.
Check optimization and hardware implementation settings
Integer division generated code contains protection against arithmetic exceptions such as division by zero, INT_MIN/-1, and LONG_MIN/-1. If you construct models making it impossible for exception triggering input combinations to reach a division operation, the protection code generated as part of the division operation is redundant.
The index search method
Evenly-spaced points
requires a division operation, which can be computationally expensive.
Identify blocks that will invoke net slope computation
When a change of fixed-point slope is not a power of two, net slope computation is necessary. Normally, net slope computation is implemented using an integer multiplication followed by shifts. Under some conditions, an alternate implementation requires just an integer division by a constant. One of the conditions is that the net slope can be very accurately represented as the reciprocal of an integer. When this condition is met, the division implementation produces more accurate numerical behavior. Depending on your compiler and embedded hardware, the division implementation might be more desirable than the multiplication and shifts implementation. The generated code might be more efficient in either ROM size or model execution size.
The Model Advisor alerts you when:
You set the Use division for fixed-point net slope computation optimization parameter to
‘On’
, but your model configuration is not compatible with this selection.Your model configuration is suitable for using division to handle net slope computation, but you do not set the Use division for fixed-point net slope computation optimization parameter to
‘On’
.
For more information, see Net Slope Computation.
Identify product blocks that are less efficient
The number of multiplications and divisions that a block performs can have a significant impact on accuracy and efficiency. The Model Advisor detects some, but not all, situations where rearranging the operations can improve accuracy, efficiency, or both.
One such situation is when a calculation using more than one division operation is computed. A general guideline from the field of numerical analysis is to multiply all the denominator terms together first, then do one and only one division. This improves accuracy and often speed in floating-point and especially fixed-point. This can be accomplished in Simulink by cascading Product blocks. Note that multiple divisions spread over a series of blocks are not detected by the Model Advisor.
Another situation is when a single Product block is configured to do more than one multiplication or division operation. This is supported, but if the output data type is integer or fixed-point, then better results are likely if this operation is split across several blocks each doing one multiplication or one division. Using several blocks allows the user to control the data type and scaling used for intermediate calculations. The choice of data types for intermediate calculations affects precision, range errors, and efficiency.
Check for expensive saturation code
Setting the Saturate on integer overflow parameter can produce condition checking code that your application might not require.
Check whether your application requires setting Block Parameters > Signal Attributes > Saturate on integer overflow. Otherwise, clear this parameter for the most efficient implementation of the block in the generated code.
Identify Questionable Fixed-Point Operations
This check identifies blocks that generate multiword operations, cumbersome multiplication and division operations, expensive conversion code, inefficiencies in lookup table blocks, and expensive comparison code.
Check for multiword operations
When an operation results in a data type larger than the largest word size of your processor, the generated code contains multiword operations. Multiword operations can be inefficient on hardware. To prevent multiword operations, adjust the word lengths of inputs to operations so that they do not exceed the largest word size of your processor. For more information on controlling multiword operations in generated code, see Fixed-Point Multiword Operations In Generated Code.
Check for expensive multiplication code
Targeting an Embedded Processor discusses the capabilities and limitations of embedded processors. Design Rules recommends that inputs to a multiply operation should not have word lengths larger than the base integer type of your processor. Multiplication with larger word lengths can always be handled in software, but that approach requires much more code and is much slower. The Model Advisor identifies blocks where undesirable software multiplications are required. Visual inspection of the generated code, including the generated multiplication utility function, will make the cost of these operations clear. It is strongly recommended that you adjust the model to avoid these operations.
Rules for Arithmetic Operations discusses the implementation details of fixed-point multiplication and division. Significant increase in complexity occurs when signals with nonzero biases are involved in multiplication and division. It is strongly recommended that you make changes to eliminate the need for these complicated operations. Extra steps are required to implement the multiplication. Inserting a Data Type Conversion block before and after the block doing the multiplication allows the biases to be removed and allows the user to control data type and scaling for intermediate calculations. In many cases the Data Type Conversion blocks can be moved to the “edges” of a (sub)system. The conversion is only done once and all blocks can benefit from simpler bias-free math.
Check for expensive division code
The rounding behavior of signed integer division is not fully specified by C language standards. Therefore, the generated code for division is too large to provide bit-true agreement between simulation and code generation. To avoid integer division generated code that is too large, in the Configuration Parameters dialog box, on the Hardware Implementation pane, set the Signed integer division rounds to parameter to the recommended value.
Identify lookup blocks with uneven breakpoint spacing
Efficiency trade-offs related to lookup table data are described in Effects of Spacing on Speed, Error, and Memory Usage. Based on these trade-offs, the Model Advisor identifies blocks where there is potential for efficiency improvements, and issues a warning when:
Lookup table input data is not evenly spaced.
Lookup table input data is not evenly spaced when quantized, but it is very close to being evenly spaced.
Lookup table input data is evenly spaced, but the spacing is not a power of two.
Check for expensive pre-lookup division
For a Prelookup or n-D Lookup Table block,
Index search method is Evenly spaced
points
. Breakpoint data does not have power of 2 spacing.
If breakpoint data is nontunable, it is recommended that you adjust the data to have even, power of 2 spacing. Otherwise, in the block parameter dialog box, specify a different Index search method to avoid the computation-intensive division operation.
Check for expensive data type conversions
When a block is configured such that it would generate inefficient code for a data type conversion, the Model Advisor generates a warning and makes suggestions on how to make your model more efficient.
Check for fixed-point comparisons with predetermined results
When you select isInf
, isNaN
, or
isFinite
as the operation for the Relational Operator
block, the block switches to one-input mode. In this mode, if the input data type is fixed
point, boolean, or a built-in integer, the output is FALSE for isInf
and isNaN
, TRUE for isFinite
. This might result in
dead code which will be eliminated by Simulink
Coder™.
Check for expensive binary comparison operations
When the input data types of a Relational Operator block are not the same, a conversion operation is required every time the block is executed. If one of the inputs is invariant, then changing the data type and scaling of the invariant input to match the other input improves the efficiency of the model.
When the inputs of a Relational Operator block have different ranges, there will be a range error when casting, and a precision loss each time a conversion is performed. You can insert Data Type Conversion blocks before the Relational Operator block to convert both inputs to a common data type that has enough range and precision to represent each input.
When the inputs of a Relational Operator block have different slope adjustment factors, the Relational Operator block is required to perform a multiply operation each time the input with lesser positive range is converted to the data type and scaling of the input with greater positive range. The extra multiplication requires extra code, slows down the speed of execution, and usually introduces additional precision loss. By adjusting the scaling of the inputs, you can eliminate mismatched slopes.
Check for expensive comparison code
When your model is configured such that the generated code contains expensive comparison code, the Model Advisor generates a warning.
Check for expensive fixed-point data types in generated code
When a design contains integer or fixed-point word lengths that do not exist on your target hardware, the generated code can contain extra saturation code, shifts, and multiword operations. By changing the data type to one that is supported by your target hardware, you can improve the efficiency of the generated code. The Model Advisor flags these expensive data types in your model. For example, the Model Advisor would flag a fixed-point data type with a word length of 17 if the target hardware was 32 bits.
Identify Blocks That Generate Expensive Rounding Code
This check alerts you when rounding optimizations are available. To check for blocks that generate expensive rounding code, the Model Advisor performs the following sub-checks:
Check for expensive rounding operations in multiplication and division
Check optimization and Hardware Implementation settings (Lookup Blocks)
Check for expensive rounding in a data type conversion
Check for expensive rounding modes in the model
Traditional handwritten code, especially for control applications, almost always uses “no effort” rounding. For example, for unsigned integers and two's complement signed integers, shifting right and dropping the bits is equivalent to rounding to floor. To get results comparable to, or better than, what you expect from traditional handwritten code, use the simplest rounding mode. In general the simplest mode provides the minimum cost solution with no overflows. If the simplest mode is not available, round to floor.
The primary exception to this rule is the rounding behavior of signed integer division. The C standard leaves this rounding behavior unspecified, but for most production targets the “no effort” mode is to round to zero. For unsigned division, everything is non-negative, so rounding to floor and rounding to zero are identical. To improve rounding efficiency, set Model Configuration Parameters > Hardware Implementation > Device details > Signed integer division rounds to using the mode that your production target uses.
Use the Integer rounding mode parameter on your model's blocks to simulate the rounding behavior of the C compiler that you use to compile code generated from the model. This setting appears on the Signal Attributes pane of the parameter dialog boxes of blocks that can perform signed integer arithmetic, such as the Product block. To obtain the most efficient generated code, change the Integer rounding mode parameter of the block to the recommended setting.
For more information on properties to consider when choosing a rounding mode, see Choosing a Rounding Method.