strange and supicious behaviour of embedded coder for generated code optimization
3 views (last 30 days)
Show older comments
Hello,
I am currently trying to optmize performances of the C code generated by Embedded Coder for MATLAB R2918b and I do not understand some strange behaviour of this process.
As a matter of fact, I have noticed that some MATLAB code using operations between complex vector and single do not lead to code I expected to see.
For example, let us examine the following MATLAB function:
y = fcn()
fIn = single(100.0 * (rand(1, 327680)+ 0.5));
divider = single(360.0);
fOut = (1i * fIn)/divider;
y = nom(fOut);
end
Then the code generated by Embedded Coder includes the following strange lines (knowing that b[] is calculated as random real values between 0 and 1):
d_0.re = 0.0F;
d_0.im = 0.0F
for (i = 0; i < 32768; i++) {
ai = (real32_T)((b[i] + 0.5) * 100.0);
if (ai == 0.0F) {
d[i].re = 0.0F;
d[i].im = 0.0F;
} else {
d[i].re = 0.0F
d[i].im = ai / 360.0F;
}
}
The same behaviour occurs when input vector "fIn" is a simple ramp from 1.0 to 100.0 or any input single vector coming from somewhere else. And in the latter case, it is very often the case in real life that values for a real signal is very closed to 0.0F but not truly 0.0F; testing a single value against 0.0F for real data seems not very clever and as a result, the condition (ai == 0.0F) may never be true.
Obviously in my example, aI is never equal to 0.0F as its minimal value can (very rarely) be 50.0; thus the condition (ai == 0.0F) is never true and the generated code is testing 32768 times a useless condition. This is not very perfoming compared with manual coding (which is often the case I must admit).
Besides, this behaviour can be confirmed by producing code coverage; in the coverage report, I could see that the lines "d[i].re = 0.0F; d[i].im =0.0F" are never reached.
I would have preferred to see a straight forward generated code like this:
for (i =0; i < 32768;i++) {
ai = (real32_T)((b[i] + 0.5) * 100.0);
d[i].re = 0.0F
d[i].im = ai / 360.0F;
}
Now my question is:
Is there any option for generated code optimization (or any other trick) to avoid producing useless condition "if (ai == 0.0F)" ?
Thank you for your attention.
Best regards.
0 Comments
Answers (5)
Jonas
on 11 Aug 2020
Edited: Jonas
on 11 Aug 2020
Check your Embedded Coder Configuration Settings. You can for example try to check 'Inline invariant signals' and set the 'Default parameter behaviour' to 'Inlined' to make sure Embedded Coder sees your variable 'divider' as invariant. From your original code, the line 'fOut = (1i * fIn)/divider;' can give issues and the coder needs to protect it against division by zero. Of course, the variable divider is always fixed to 360.0 but the Configuration Parameters you have at the moment do not allow inlining this value.
There may be other Configuration Parameters which are helpful but I would need to test/try them myselves to see the effect on the code. It's under Configuration Parameters > Code Generation > Optimization > Advanced parameters.
0 Comments
Didier Billard
on 11 Aug 2020
1 Comment
Jonas
on 11 Aug 2020
Is your setting for 'Remove code that protects against division arithmetic exceptions' checked? Could you maybe share a screenshot of this Configuration Parameters page, for the 'Advanced parameters'?
Didier Billard
on 12 Aug 2020
Edited: Walter Roberson
on 12 Aug 2020
1 Comment
Walter Roberson
on 12 Aug 2020
Does the code produce incorrect answers? If not, then you have no reason not to trust it to produce correct answers.
If what you happen to need is to trust that it will produce the most efficient possible code, then that is a different issue. Any tool that generates code for a different language must trust that the compiler optimizes well. It is not appropriate for a mechanical code generation tool to get into details such as variable lifetime analysis, because people who use the generated code have different requirements at different times. Tools such as Embedded Coder should not have a lot of knowledge about a lot of different toolchains and their optimization engines such that Embedded Coder should be using techniques such as deliberately inserting junk code in order to force a toolchain to react a particular way so that Embedded Coder would reach a particular goal.
If you need very high efficiency in the generated code, then you should be reading all of the machine language dumps of your toolchain's output.
See Also
Categories
Find more on Deployment, Integration, and Supported Hardware in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!