I ran the profiler on my Simulink model and realized that the "To Workspace" block is using 20% of the total simulation time. Because this model is ran more than one time, I'm looking for a way to increase its performance.
Hence, is there an alternate solution to using the "To Workspace" block that would increase my model global performance?
Yes, you can use Signal Logging. The various approaches to logging simulation results are discussed in the documentation under Export Simulation Data. Finally, see also View Simulation Results for alternative approaches. My personal recommendation would be signal logging or a To File block.
According to my general understanding of memory management, reserving a fixed memory block takes less time than expanding it in each timestep. So, it might be useful to limit the number of data points to be logged, that the memory space reserved for your data set will not be dynamically increased at every timestep. Of course this would be only valid if you would know the number of data points and therefore number of steps in simulation prior to start of the simulation, which can be achieved by a fixed step size solver (if applicable by your simulation system setuo). Thus pre-allocation of the workspace array might save you some time in terms of not reaching the memory management system at each timestep.
Related
Some general Modelica advice?
We've built a model with ~2000 equations and three vectors of input from measured data. Using OpenModelica, attempts at simulation have begun to hang in the translation stage (which runs for hours where it used to take less than a minute) and now I regularly "lose connection to omc.exe." Is there perhaps something cumulative occurring that's degrading translation/compilation performance?
In general, are there any good rules of thumb for keeping simulations lighter and faster? I realize that, depending on the couplings, additional equations could be exponentially increasing the size of the resulting system of equations - could this be a problem?
Thanks for your thoughts!
It shouldn't take that long. Seems like a bug.
You can report this bug here:
https://trac.openmodelica.org/OpenModelica (New Ticket).
If your model is public you can post it there, if not you can contact the OpenModelica team privately.
I did some cleaning in the code; and got the part that repeats 12x (the module) down to ~180 equations; in the process I reduced the size of my input vectors (and also a 2D look-up table the module refers to) by quite a bit - they're both down to a few hundred values. It's working now--simulations run in reasonable time, a few minutes each.
Since all these tables were defined within Modelica functions (as you pointed out, Mr. Tiller) perhaps shrinking them helped to improve the performance. I had assumed that all that data just got spread out in a memory array, without going through any real processing, but maybe that's not the case...time to know more about what's going on under the hood in this environment (as always).
Thanks for the help!
I want to run a simulation which includes SimEvent blocks (thus only Normal option is available for sim run) for a large number of times, like at least 1000. When I use sim it compiles the program every time and I wonder if there is any other solution which just run the simulation repeatedly in a faster way. I disabled Rebuild option from Configuration Parameter and it does make it faster but still takes ages to run for around 100 times.
And single simulation time is not long at all.
Thank you!
It's difficult to say why the model compiles every time without actually seeing the model and what's inside it. However, the Parallel Computing Toolbox provides you with the ability to distribute the iterations of your model across several cores, or even several machines (with the MATLAB Distributed Computing Server). See Run Parallel Simulations in the documentation for more details.
I have noticed that the first time I run a script, it takes considerably more time than the second and third time1. The "warm-up" is mentioned in this question without an explanation.
Why does the code run faster after it is "warmed up"?
I don't clear all between calls2, but the input parameters change for every function call. Does anyone know why this is?
1. I have my license locally, so it's not a problem related to license checking.
2. Actually, the behavior doesn't change if I clear all.
One reason why it would run faster after the first time is that many things are initialized once, and their results are cached and reused the next time. For example in the M-side, variables can be defined as persistent in functions that can be locked. This can also occur on the MEX-side of things.
In addition many dependencies are loaded after the first time and remain so in memory to be re-used. This include M-functions, OOP classes, Java classes, MEX-functions, and so on. This applies to both builtin and user-defined ones.
For example issue the following command before and after running your script for the first run, then compare:
[M,X,C] = inmem('-completenames')
Note that clear all does not necessarily clear all of the above, not to mention locked functions...
Finally let us not forget the role of the accelerator. Instead of interpreting the M-code every time a function is invoked, it gets compiled into machine code instructions during runtime. JIT compilation occurs only for the first invocation, so ideally the efficiency of running object code the following times will overcome the overhead of re-interpreting the program every time it runs.
Matlab is interpreted. If you don't warm up the code, you will be losing a lot of time due to interpretation instead of the actual algorithm. This can skew results of timings significantly.
Running the code at least once will enable Matlab to actually compile appropriate code segments.
Besides Matlab-specific reasons like JIT-compilation, modern CPUs have large caches, branch predictors, and so on. Warming these up is an issue for benchmarking even in assembly language.
Also, more importantly, modern CPUs usually idle at low clock speed, and only jump to full speed after several milliseconds of sustained load.
Intel's Turbo feature gets even more funky: when power and thermal limits allow, the CPU can run faster than its sustainable max frequency. So the first ~20 seconds to 1 minute of your benchmark may run faster than the rest of it, if you aren't careful to control for these factors.
Another issue not mensioned by Amro and Marc is memory (pre)allocation.
If your script does not pre-allocate its memory it's first run would be very slow due to memory allocation. Once it completed its first iteration all memory is allocated, so consecutive invokations of the script would be more efficient.
An illustrative example
for ii = 1:1000
vec(ii) = ii; %// vec grows inside loop the first time this code is executed only
end
I am working on the development of an Iterative Learning Controller for a simple transfer function.
The iterations are controlled by the external matlab loop.
But the error e(k) (k is trial number) is not updating ... as the trials increases.
Please detect the error I've commited.
Thanks and Regards.
You might have solved the problem. But as the question is still open, I would like to add something here.
First of all, you might want to check the usage of "memory" block. "The Memory block holds and delays its input by one major integration time step." The reason why the error wasn't updating is that the output of your plant produced was the same in each iteration(you defined external loop). The memory block only delayed one step of your U(K), not the whole iteration.
You might want to store the error of each iteration to workspace, and use it for the next iteration.
The memory should be a vector with a lenght of the single iteration. Not just single value. Delay block can store multiple past samples.
This guy did probably what you were looking for: https://github.com/arthurrichards77/iterative-learning-control
Background:
I have inherited a Discrete-Event Simulation MATLAB model and wish to automate and speed it's execution. Rather than calling sim(modelName) and having MATLAB run interpreted code, I would like a solution akin to calling system('modelName.exe ...'). My motivation for this comes from initial tests which suggest that a speed increase of nearly 1000%. I have managed to use the Real-Time Workshop with the Rapid Simulation target to produce an exe with static memory allocation. The problem is that there are Embedded MATLAB Function Blocks in the model for which the parameters will vary in size and shape in each run. And there will be hundreds if not thousands of runs.
According to the MathWorks documentation:
Dynamic Memory Allocation Not Supported for Embedded MATLAB Function Blocks:
"You cannot use dynamic memory allocation for variable-size data in Embedded MATLAB Function blocks. Use bounded instead of unbounded variable-size data."
Question:
What would be a potential workaround for this limitation?
Thoughts:
Use a static variable sizes which are sufficiently large, and additionally pass int variables / tunable parameters to explicitly window the portion of the data to range over.
S-Functions?
What I'm implementing today: Programmatically recompile the simulation each time it's called to generate static code, dynamically.
Port everything to a real/modern programming language such as python or c++.
Keywords:
MATLAB dynamic memory allocation embedded Discrete Event Simulation Real-Time Workshop Simulink SimEvents Tunable Parameters
Following up on this years later... We went with the dynamic static recompilation I had implemented that day for a year or so, then another stats developer rewrote it in c++. Using the maximum possible memory every run simply wasn't a feasible waste of computing resources.
You should view this webinar : http://www.mathworks.com/company/events/webinars/wbnr43180.html . It explains an automatic solution similar to your first thought.