Opened 9 years ago

Closed 9 years ago

Last modified 7 years ago

#3685 closed defect (fixed)

SimCode generation time does not scale properly with the system size

Reported by: Francesco Casella Owned by: Willi Braun
Priority: critical Milestone:
Component: Code Generation Version: v1.9.4-dev-nightly
Keywords: Cc:

Description

Consider the results on the compilation of the models ScalableTestSuite.Electrical.TransmissionLine.ScaledExperiments.TransmissionLineModelica_N_XX reported here:

https://test.openmodelica.org/libraries/ScalableTestSuite_Experimental/BuildModelRecursive.html

It is immediate to notice that the SimCode time scales approximately with the square of the sytem size. This is not right, as we might expect that the amount of code that describes these models is roughly proportional to their size. For large models, this can lead to prohibitevely high times.

It might be the case that the implementation of the functionalities in SimCode contains some double recursion that originates this behaviour.

Please investigate if this is the case and, if so, try to reimplement the functions avoiding the double recursion and the quadratic growth of the execution time.

Change History (14)

comment:1 by Francesco Casella, 9 years ago

I see there's some improvement after PR447. However, I still see almost quadratic scaling, see e.g. the ScalableTestSuite.Mechanical.Strings.ScaledExperiments.StringModelica_N_XX models.

comment:2 by Willi Braun, 9 years ago

Yeah, that's also the reason I haven't closed it ;).
However, I guess I found the other place already also fixed is almost.
So I'll hope to push quite soon and then close than.

comment:3 by Willi Braun, 9 years ago

An further improvement should result from PR473. Let's see and wait for the results from the coverage run.

comment:4 by Henning Kiel, 9 years ago

Using callgrind (OSX) I see that for simple models already at least 1/3 of the time is spent with GC. And quickly several GB of RAM were allocated and freed by GC.

One possible candidate is the massive use of listAppend, which for each call duplicates the first list and appends the second. If that is used recursively/in a loop the memory consumption grows quadratically (and GC time should also grow like this).

To reduce the overhead, I implemented a function listAppendTail() which assumes that the first list is sort of "input output", so that it expects more calls appending to that list.

function test_appendListTail<T>
  input list<list<T>> inLst;
  output list<T> outLst = {};
protected
  list<T> tail = {}; // pseudo list to quickly access last element and determine if the first list already was copied.
algorithm
  for l in inLst loop
    (outLst, tail) := listAppendTail(outLst, tail, l);
  end for;
end test_appendListTail;

Using ordinary listAppend() like the following should not suffer from this slow-down:

for ... loop
  finalLst := listAppend(nextLst, finalLst);
end for;

comment:5 by Willi Braun, 9 years ago

Some more improvements for the SimCode phase are done in PR490.

SimCode timings for ScalableTestSuite.Mechanical.Strings.ScaledExperiments.StringModelica:

Nwithout PR490with PR490
40.3959067570.277792809
80.7646681690.410150604
161.8767111650.714030386
326.1072744491.600489924
6424.214634183.889687883

and for TestSuite.Electrical.TransmissionLine.ScaledExperiments.TransmissionLineModelica:

Nwithout PR490with PR490
1600.591807950.548860394
3201.933006441.144715092
6404.1545658552.731017459
128013.9420110156.910039283

It seems still not linear, but I suspect this might connect to the evaluation of start-values, where we use the module evalFunc and there exist an other open ticket #3553.

comment:6 by Francesco Casella, 9 years ago

These are indeed excellent results!

I have started a Hudson job with the ScalableTestSuite library to get a more comprehensive view of the effects of the recent commits - results should be soon available here. Let's see what we get.

Last edited 9 years ago by Francesco Casella (previous) (diff)

comment:7 by Willi Braun, 9 years ago

I think this job is based on a fresh run of LINUX_NIGHTLY_BUILD, so let's wait a bit for the newest version, that contains also ​the changes from PR490.

comment:8 by Adrian Pop, 9 years ago

This job is based on job OpenModelica_TEST_ALL_LIBRARIES which builds a new OMC and runs the coverage testing so you only get one new OMC each night at 2:00. I think we should change it so it builds the new OMC. I'll look into it.

comment:9 by Adrian Pop, 9 years ago

I now changed LibraryExperimental job to *always* build the newest OMC and then run the coverage with it.

comment:10 by Francesco Casella, 9 years ago

Thanks! I always forgot that this job would use the latest nightly, but this is now much better. On-demand jobs like this should not depend on others.

comment:11 by Martin Sjölund, 9 years ago

Milestone: 1.9.41.9.5

Milestone pushed to 1.9.5

comment:12 by Martin Sjölund, 9 years ago

Milestone: 1.9.51.10.0

Milestone renamed

comment:13 by Francesco Casella, 9 years ago

Resolution: fixed
Status: newclosed

The situation has further improved now, and the scaling is now only slightly superlinear, so I'm closing this ticket.

comment:14 by Martin Sjölund, 7 years ago

Milestone: 1.10.0

Milestone deleted

Note: See TracTickets for help on using tickets.