如何在Dymola/Modelica中消除死代码

5
我正在尝试简化一个非常复杂的模型以提高性能,并注意到当我向信号总线添加或删除变量时,特别是多体框架时,会有很大的性能变化。
我想知道是否有任何设置可以消除不涉及生成模型输出的代码。
我尝试将总线连接器设置为“受保护”,以确保它不成为输出,但仍会生成计算它们的代码。
我还尝试了这些标志,但它并没有消除死代码:
Advanced.Embedded.OptimizeForOutputs=true;
Advanced.SubstituteVariablesUsedOnce=true;
Evaluate=true;
Advanced.EvaluateAlsoTop=true;
Advanced.SubstituteVariablesUsedOnce=true;

这是一个简单的模型来复制该场景:

simple modelica model

model TestBusConnector
  extends Modelica.Icons.Example;
protected 
        Modelica.Blocks.Examples.BusUsage_Utilities.Interfaces.ControlBus controlBus
    annotation (Placement(transformation(extent={{-20,-20},{20,20}})));
public 
  Modelica.Blocks.Sources.Sine sine(freqHz=1)
    annotation (Placement(transformation(extent={{-40,-50},{-20,-30}})));
  Modelica.Blocks.Sources.Constant const(k=0)
    annotation (Placement(transformation(extent={{-10,50},{10,70}})));
  Modelica.Blocks.Interfaces.RealOutput y
    annotation (Placement(transformation(extent={{90,-10},{110,10}})));
equation 
  connect(y, const.y) annotation (Line(points={{100,0},{60,0},{60,60},{11,60}}, color={0,0,127}));
  connect(sine.y, controlBus.testBusVariable)
    annotation (Line(points={{-19,-40},{0,-40},{0,0}}, color={0,0,127}));
  annotation (experiment(__Dymola_fixedstepsize=0.001, __Dymola_Algorithm="Euler"),
      __Dymola_experimentFlags(Advanced(
        InlineMethod=0,
        InlineOrder=2,
        InlineFixedStep=0.001)),
    __Dymola_experimentSetupOutput(
      states=false,
      derivatives=false,
      inputs=false,
      outputs=false,
      auxiliaries=false,
      equidistant=false,
      events=false));
end TestBusConnector;

以下是从Dymola 2019 FD01生成的代码:

include <dsblock6.c>

PreNonAliasNew(0)
StartNonAlias(0)
DeclareVariable("sine.amplitude", "Amplitude of sine wave", 1, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.freqHz", "Frequency of sine wave [Hz]", 1, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.phase", "Phase of sine wave [rad|deg]", 0, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.offset", "Offset of output signal", 0, 0.0,0.0,0.0,0,513)
DeclareVariable("sine.startTime", "Output = offset for time < startTime [s]", 0,\
 0.0,0.0,0.0,0,513)
DeclareVariable("sine.y", "Connector of Real output signal", 0.0, 0.0,0.0,0.0,0,512)
DeclareVariable("const.k", "Constant output value", 0, 0.0,0.0,0.0,0,513)
DeclareVariable("const.y", "Connector of Real output signal", 0, 0.0,0.0,0.0,0,513)
DeclareOutput("y", "", 0, 0.0, 0.0,0.0,0.0,0,513)
DeclareAlias2("controlBus.testBusVariable", "Connector of Real output signal", \
"sine.y", 1, 5, 5, 1028)
EndNonAlias(0)

#define DymolaHaveUpdateInitVars 1
#include <dsblock5.c>

DYMOLA_STATIC void UpdateInitVars(double*time, double* X_, double* XD_, double* U_, double* DP_, int IP_[], Dymola_bool LP_[], double* F_, double* Y_, double* W_, double QZ_[], double duser_[], int iuser_[], void*cuser_[],struct DYNInstanceData*did_,int initialCall) {
}
StartDataBlock
EndDataBlock

翻译后的Modelica代码(dsmodel.mof)仍然包含正弦块的计算。

// Translated Modelica model generated by Dymola from Modelica model 
//  TEMP.TEST.TestBusConnector


// -----------------------------------------------------------------------------

// Initial Section
  sine.amplitude := 1;
  sine.freqHz := 1;
  sine.phase := 0;
  sine.offset := 0;
  sine.startTime := 0;
  const.k := 0;
  const.y := 0;
  y := 0.0;




// -----------------------------------------------------------------------------

// Conditionally Accepted Section
  sine.y := (if time < 0 then 0 else sin(6.283185307179586*time));

// -----------------------------------------------------------------------------

// Eliminated alias variables
  // To have eliminated alias variables listed, set
  //   Advanced.OutputModelicaCodeWithAliasVariables = true
  // before translation. May give much output.

理想情况下,我希望这个模型能够翻译成以下内容:
y := 0.0;
3个回答

3
其他答案行不通的原因是:你的模型与问题不一致。 "我想知道是否有任何设置可以消除与生成模型输出无关的代码"。
通过将控制总线连接到sine.y,您隐含地创建了一个输出,因此sine.y参与了生成模型输出的过程。
可以通过以下一种方式避免这种情况:
  • 删除sine.y和controlBus之间的连接
  • 将controlBus更改为受保护的
  • 更改controlBus,使其不在顶层

1
感谢您的回复。我尝试了您列出的所有解决方案。然而,翻译后的Modelica和生成的代码仍然包含正弦块。 - Srikanth Sivaramakrishnan

1

这不是对你问题的直接回答,但仍然可以帮助提高性能。你试图避免的计算工作的一部分是由于在结果文件中计算变量而产生的。可以通过以下设置来避免:

Selection of variables to store in the result file

这可以通过在模型本身中使用注释来设置:
  annotation (__Dymola_experimentSetupOutput(
      states=false,
      derivatives=false,
      inputs=false,
      auxiliaries=false));

1
你好 Markus,我已经在注释中关闭了所有输出。我不直接运行dymosim.exe,而是将代码导出供实时系统使用。这就是为什么我正在尝试在C代码级别减少不必要元素的计算。 - Srikanth Sivaramakrishnan
1
明白了。在这种情况下,我的回答并没有帮助太多。 期待其他答案,因为我不知道如何进行这种优化。 - Markus A.

1

还有另一个标志可以帮助。它并不会给出你期望的结果,但仍然可能很有用:

Advanced.Define.AutoRemoveAuxiliaries = true;

Dymola用户手册2描述该标志如下:

删除对辅助变量的代码,这些变量既不影响仿真状态也不影响输出。这会稍微提高性能。

从这个描述中,我的期望是生成的代码与您请求的代码相同,但不幸的是事实并非如此。

谢谢您的回复。我已经启用了这个标志,但它仍然无法删除与生成输出无关的代码(正弦块)。 - Srikanth Sivaramakrishnan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接