MATLAB Answers

Best Practice for Defining Large Constant Array in Function (Must Code-generate)

1 view (last 30 days)
Alan Bindemann
Alan Bindemann on 9 Apr 2020
Commented: Sean de Wolski on 16 Apr 2020
I have a function that uses a largish array of constant Legendre polynomial coefficients. I'm curious, from a performance standpoint, of the best way to define these constants in a MATLAB Function. The simplest approach is to define them directly:
function y = foo(x)
%#codegen
coeff = [1,2,3,3;...
2,34,45,5;...
45,565,56754,43;
.
. % Many lines of coeff.
.
.];
y = someFunction(x,coeff);
end
I could make coeff persistent as follows, but am not sure if there is any performance benefit of doing this:
function y = foo(x)
%#codegen
persistent coeff
if isempty(coeff)
coeff = [1,2,3,3;...
2,34,45,5;...
45,565,56754,43;
.
. % Many lines of coeff.
.
.];
end
y = someFunction(x,coeff);
end
I'm curious about the consesus on best practice in this circumstance, I need the resulting function to code-generate in a Simulink MATLAB function.

  5 Comments

Show 2 older comments
Alan Bindemann
Alan Bindemann on 10 Apr 2020
Jeff,
Thanks for your reply. Based on your suggestion I tried this, and was surprised that this approach would work in a MATLAB function block in Simulink. (I didn't think object oriented code was supported in MATLAB function blocks).
The speed with the object oriented approach is comparable to a function based approach with one caveat. To get comparable speed, the constant properties needs to be copied into a local variable in the static function. Otherwise, repeated references to the constant property (say in a loop) tend to make the function many times slower. Here's an example with two methods. I found that the second implementation is much (100x) faster than the first one.
classdef foo
properties(Constant)
coeff = [1,2,3,3;...
2,34,45,5;...
45,565,56754,43;
.
. % 100 total lines of coeff.
.
.];
end
methods(Static)
function y = someFunctionThatIsReallySlow(x)
y = 0;
% Bogus loop example (for illustration)
for i=1:100
for j=1:4
y = y + foo.coeff(i,j)*x^j; % Refer to constant property many times
end
end
end
function y = someFunctionThatIsMuchFaster(x)
coeff = foo.coeff % Pull constants into local variable once
y = 0;
% Bogus loop example (for illustration)
for i=1:100
for j=1:4
y = y + coeff(i,j)*x^j; % Refer to local variable
end
end
end
end
end
Thanks for your help. Still not sure which way is best. The function approach is simplest and has the best speed. The object approach might be cleaner (especially if you favor objects) but not any faster. The fact that it would run in Simulink as a MATLAB function came as a surpise to me.
Jeff Miller
Jeff Miller on 11 Apr 2020
Thanks for testing it. That's very disappointing performance in the case of the ReallySlow version of the function. Maybe it would be faster as a handle class.
But if the class doesn't speed things up and the coefficients are not used anywhere else, it's pretty hard to see any reason to prefer it over the simpler plain function approach
Alan Bindemann
Alan Bindemann on 14 Apr 2020
Jeff,
I tried it as a handle class and didn't notice any difference in performance. The only other thought I had on this was to call the coder.const function when setting the coefficients. This might help with performance in the generated code. I didn't see any difference in MATLAB or in Simulink when I did this, but wouldn't expect to either.
coeff = coder.const([1,2,3,3;...
2,34,45,5;...
45,565,56754,43;
.
. % Many lines of coeff.
.
.]);

Sign in to comment.

Answers (1)

Sean de Wolski
Sean de Wolski on 10 Apr 2020
Edited: Sean de Wolski on 10 Apr 2020
Look at using System Objects and the MATLAB System block in Simulink. These are optimized for streaming workflows and code generation.

  2 Comments

Alan Bindemann
Alan Bindemann on 10 Apr 2020
Sean,
From the MathWorks Documentation help:
"System Objects vs. MATLAB Functions
Many System objects have MATLAB® function counterparts. For simple, one-time computations, use MATLAB functions. However, if you need to design and simulate a system with many components, use System objects. Using System objects is also appropriate if your computations require managing internal states, have inputs that change over time or process large streams of data."
I think what I'm doing in this case is a simple one-time computation, that doesn't involve internal states, but largish amounts of constant data (though it could be called with time-changing inputs in a Simulink model). Are there aspects of System Object that would improve performance over straight functions in this case?
In my experience MATLAB objects can incur hidden performance penalties that traditional functions avoid unless you are aware fo the pitfalls and code your objects around them. The example above is a case in point.
Ideally, in cases like this one, our team wants a single solution that could be called from MATLAB as well as from Simulink and also permits code-generation. A function or class (in MATLAB) and MATLAB Function block (in Simulink) come close to this when the MATLAB Function block code body is a single line call as shown below:
function y=someFunction(x)
%#codegen
y = foo.someFunctionThatIsMuchFaster(x);
end
Are there fundamental differences in System Objects over regular MATLAB objects (or functions) that recommend their use in this case?
Sean de Wolski
Sean de Wolski on 16 Apr 2020
System objects are fit well for the dual use case that you point out. I.e. use in MATLAB or direct reuse in Simulink with the MATLAB System Block.
I don't understand all of the internals, but they're supposed to be efficient in how the JIT or generated code manage things to make the step() method as fast as possible for real-time systems. Hence why the DSP System Toolbox has many of these objects all geared for code generation. If your states aren't changing, they may be of little value. In my experience, much of the OO overhead was improved in >=R2015b with the new MATLAB execution engine.

Sign in to comment.