Avoiding Unwanted Data Copies in Simulink Generated Code via Reusing I/O
Recently, we've had a few customers ask if it's possible to configure their models to alter values on a bus that goes into and out of their model without making a data copy. There are several ways to do this with Embedded Coder®, but we'll focus on models which pass their inputs and outputs as arguments. In particular, we'll show how to pass arguments by reference in the generated code from for a Model block. This technique can be used to eliminate unnecessary copies of variables from input ports to output ports. This can lead to more efficient code.
The Model
Let's say we have a model that operates on its bus argument. The input and output to this model have the same bus type, which for this demonstration includes elements, b1, a boolean, and d1, a double. In principle, these are two of many elements. Pressing CTRL+B generates code for the model.
The Code
The model modifies the value of d1 on the bus based on the value of b1. If we generate code from this model, we get the following step function:
void A_step(my_bus *arg_in, my_bus *arg_out)
{
real_T tmp;
*arg_out = *arg_in;
if (arg_in->b1) {
tmp = -2.5;
} else {
tmp = 2.5;
}
arg_out->d1 = tmp + arg_in->d1;
}
Notice that the step function has two arguments, arg_In1 and arg_Out1, and on line 4, the code copies the input to the ouput. If this were a large bus, the copy could be quite expensive, so we'd like to eliminate it.
A More Efficient Code
In order to eliminate the copy, we can open the Code Mappings panel with CTRL+SHIFT+C and go to the Functions tab. Once there, click on the A_step hyperlink in the Function Preview column.
The hyperlink will open a new window which will allow us to configure the C step function interface for our model.
To make our argument shared, we make sure the Configure arguments for Step function prototype is checked and then set the C Identifier Name for the input and output ports to the same value. In our case, let's call it arg_shared. When we re-generate code, we get:
void A_step(my_bus *arg_shared)
{
real_T tmp;
if (arg_shared->b1) {
tmp = -2.5;
} else {
tmp = 2.5;
}
arg_shared->d1 += tmp;
}
Notice that there is only a single argument to the step function and the copy is elimiated, which leads to much more efficient code.
Now It's Your Turn
How are you avoiding unwanted copies in your generated code? What kinds of improvements to generated code efficiency would you find helpful?
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.