strange and supicious behaviour of embedded coder for generated code optimization
5 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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 comentarios
Respuestas (5)
Jonas
el 11 de Ag. de 2020
Editada: Jonas
el 11 de Ag. de 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 comentarios
Didier Billard
el 11 de Ag. de 2020
1 comentario
Jonas
el 11 de Ag. de 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
el 12 de Ag. de 2020
Editada: Walter Roberson
el 12 de Ag. de 2020
1 comentario
Walter Roberson
el 12 de Ag. de 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.
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!