Main Content

Avoid Data Copies of Function Inputs in Generated Code

You can reduce the number of copies in your generated code by writing functions that use the same variable as both an input and an output. For example:

function A = foo( A, B ) %#codegen
A = A * B;
end

This coding practice uses a reference parameter optimization. When a variable acts as both input and output, the generated code passes the variable by reference instead of redundantly copying the input to a temporary variable. In the preceding example, input A is passed by reference in the generated code because it also acts as an output for function foo:

...
/* Function Definitions */
void foo(double *A, double B)
{
    *A *= B;
}
...

The reference parameter optimization reduces memory usage and execution time, especially when the variable passed by reference is a large data structure. To achieve these benefits at the call site, call the function with the same variable as both input and output.

By contrast, suppose that you rewrite function foo without the optimization:

function y = foo2( A, B ) %#codegen
y = A * B;
end

The generated code passes the inputs by value and returns the value of the output:

...
/* Function Definitions */
double foo2(double A, double B)
{
   return A * B;
}
...

In some cases, the output of the function cannot be a modified version of its inputs. If you do not use the inputs later in the function, you can modify your code to operate on the inputs instead of on a copy of the inputs. One method is to create additional return values for the function. For example, consider the code:

function y1=foo(u1) %#codegen
  x1=u1+1;
  y1=bar(x1);
end

function y2=bar(u2)
  % Since foo does not use x1 later in the function,
  % it would be optimal to do this operation in place
  x2=u2.*2;
  % The change in dimensions in the following code
  % means that it cannot be done in place
  y2=[x2,x2];
end

You can modify the code to eliminate redundant copies.

function y1=foo(u1) %#codegen
  u1=u1+1;
  [y1, u1]=bar(u1);
end

function [y2, u2]=bar(u2)
    u2=u2.*2;
  % The change in dimensions in the following code
  % still means that it cannot be done in place
  y2=[u2,u2];
end

The reference parameter optimization does not apply to constant inputs. If the same variable is an input and an output, and the input is constant, the code generator treats the output as a separate variable. For example, consider the function foo:

function A = foo( A, B ) %#codegen
A = A * B;
end

Generate code in which A has a constant value 2.

codegen -config:lib foo -args {coder.Constant(2) 3} -report

The generated code defines the constant A and returns the value of the output.

...
#define A                              (2.0)
...
double foo(double B)
{
  return A * B;
}
...