Opened 6 years ago

Last modified 6 years ago

#4957 new defect

Inefficient code generated for record derivatives

Reported by: Per Östlund Owned by: Lennart Ochel
Priority: critical Milestone: Future
Component: Code Generation Version: v1.13.0-dev-nightly
Keywords: Cc: Willi Braun

Description

The backend generates very inefficent code in some cases involving records, for example in ScalableTestSuite.Thermal.Advection.ScaledExperiments.SteamPipe_N_10 (and presumably any model using the same parts of Modelica.Media). Looking at the omc_$DER$Modelica$PMedia$PWater$PIF97__Utilities$PwaterBaseProp__ph function in the _functions.c file for example, there's a line in the Modelica code that looks like:

 g := Modelica.Media.Water.IF97_Utilities.BaseIF97.Basic.g1(p, aux.T);

This is translated into the following C-code (line 6213 for me):

 tmp1 = omc_Modelica_Media_Water_IF97__Utilities_BaseIF97_Basic_g1(threadData, _p, _aux._T);
 _g._p = tmp1._p;
 _g._T = tmp1._T;
 _g._R = tmp1._R;
 _g._pi = tmp1._pi;
 _g._tau = tmp1._tau;
 _g._g = tmp1._g;
 _g._gpi = tmp1._gpi;
 _g._gpipi = tmp1._gpipi;
 _g._gtau = tmp1._gtau;
 _g._gtautau = tmp1._gtautau;
 _g._gtaupi = tmp1._gtaupi;

Assigning each field of _g separately is a bit weird but might be necessary for all I know, but at least it only calls the functions once. Immediately following this is the following code though (I've shortened the identifiers in the code to make it readable, the actual C-code is much larger):

 $funDERg._p = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._p;
 $funDERg._T = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._T;
 $funDERg._R = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._R;
 $funDERg._pi = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._pi;
 $funDERg._tau = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._tau;
 $funDERg._g = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._g;
 $funDERg._gpi = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._gpi;
 $funDERg._gpipi = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._gpipi;
 $funDERg._gtau = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._gtau;
 $funDERg._gtautau = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._gtautau;
 $funDERg._gtaupi = omc_$DER$g1(threadData, _p, _aux._T, $funDERp, $funDERaux._T)._gtaupi;

It seems like this is calculating some kind of derivative of g, but it does so by calling the omc_$DER$g1 function once for each record field. This pattern is repeated all over the generated code, causing a huge amount of unnecessary function calls. And at least g1 is quite large and expensive to call, so optimizing this to only call the function once would probably improve the simulation performance quite a bit for models like this.

Change History (1)

comment:1 by Per Östlund, 6 years ago

Cc: Willi Braun added
Note: See TracTickets for help on using tickets.