The code generator optimizes generated code for vector signal assignments by trying to replace for
loop controlled element assignments and memcpy
function calls with pointer assignments. Pointer assignments avoid expensive data copies. Therefore, they use less stack space and offer faster execution speed than for
loop controlled element assignments and memcpy
function calls. If you assign large data sets to vector signals, this optimization can result in significant improvements to code efficiency.
To apply this optimization:
Verify that your target supports the memcpy
function.
Determine whether your model uses vector signal assignments (such as Y=expression
) to move large amounts of data. For example, your model could use a Selector block to select input elements from a vector, matrix, or multidimension signal.
On the Optimization pane, the Use memcpy for vector assignment parameter, which is on by default, enables the associated Memcpy threshold (bytes) parameter.
Examine the setting of Memcpy threshold (bytes). By default, it specifies 64 bytes as the minimum array size for which memcpy
function calls or pointer assignments can replace for
loops in the generated code. Based on the array sizes in your application's vector signal assignments, and target environment considerations on the threshold selection, accept the default value or specify another array size.
Consider the following model named rtwdemo_pointer_conversion. This model uses a Switch block to assign data to a vector signal. This signal then feeds into a Bus Selector block.
In the Configuration Parameters dialog box, clear the Use memcpy for vector assignment parameter.
Create a temporary folder for the build and inspection process.
Press Ctrl+B to generate code.
### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets built: Model Action Rebuild Reason =========================================================================================================== rtwdemo_pointer_conversion Code generated and compiled Code generation information file does not exist. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 11.488s
View the generated code without the optimization. Here is a portion of rtwdemo_pointer_conversion.c
.
/* Model step function */ void rtwdemo_pointer_conversion_step(void) { int32_T i; int16_T rtb_dataX[100]; int16_T rtb_dataY[100]; for (i = 0; i < 100; i++) { /* Switch generated from: '<Root>/Switch' incorporates: * Inport: '<Root>/In1' */ if (rtU.In1) { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant' */ rtb_dataX[i] = rtCP_Constant_Value[i]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant1' */ rtb_dataY[i] = rtCP_Constant1_Value[i]; } else { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant2' */ rtb_dataX[i] = rtCP_Constant2_Value[i]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant3' */ rtb_dataY[i] = rtCP_Constant3_Value[i]; } /* End of Switch generated from: '<Root>/Switch' */ } /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates: * Inport: '<Root>/In2' * Outport: '<Root>/Out1' */ /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic' * Input0 Data Type: Integer S16 * Input1 Data Type: Integer S16 * Input2 Data Type: Integer S16 * Output0 Data Type: Integer S16 * Lookup Method: Linear_Endpoint * */ LookUp_S16_S16( &(rtY.Out1), &rtb_dataY[0], rtU.In2, &rtb_dataX[0], 99U); }
Without the optimization, the generated code contains for
loop controlled element assignments.
In the Configuration Parameter dialog box, select the Use memcpy for vector assignment parameter.
Generate code.
### Starting build procedure for: rtwdemo_pointer_conversion ### Successful completion of build procedure for: rtwdemo_pointer_conversion Build Summary Top model targets built: Model Action Rebuild Reason ========================================================================================== rtwdemo_pointer_conversion Code generated and compiled Generated code was out of date. 1 of 1 models built (0 models already up to date) Build duration: 0h 0m 10.644s
View the generated code without the optimization. Here is a portion of rtwdemo_pointer_conversion.c
.
/* Model step function */ void rtwdemo_pointer_conversion_step(void) { const int16_T *rtb_dataX_0; const int16_T *rtb_dataY_0; /* Inport: '<Root>/In1' */ if (rtU.In1) { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant' */ rtb_dataX_0 = &rtCP_Constant_Value[0]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant1' */ rtb_dataY_0 = &rtCP_Constant1_Value[0]; } else { /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant2' */ rtb_dataX_0 = &rtCP_Constant2_Value[0]; /* Switch generated from: '<Root>/Switch' incorporates: * Constant: '<Root>/Constant3' */ rtb_dataY_0 = &rtCP_Constant3_Value[0]; } /* End of Inport: '<Root>/In1' */ /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates: * Inport: '<Root>/In2' * Outport: '<Root>/Out1' */ /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic' * Input0 Data Type: Integer S16 * Input1 Data Type: Integer S16 * Input2 Data Type: Integer S16 * Output0 Data Type: Integer S16 * Lookup Method: Linear_Endpoint * */ LookUp_S16_S16( &(rtY.Out1), &rtb_dataY_0[0], rtU.In2, &rtb_dataX_0[0], 99U); }
Because the setting of the Memcpy threshold (bytes) parameter is below the array sizes in the generated code, the optimized code contains pointer assignments for the vector signal assignments.
Memcpy threshold (bytes) | Use memcpy for vector assignment