Simulink Best Practices for Large-Scale Modeling | Simulink Best Practices for Large-Scale Modeling, Part 1 - MATLAB & Simulink
Video Player is loading.
Current Time 0:00
Duration 21:45
Loaded: 0.00%
Stream Type LIVE
Remaining Time 21:45
 
1x
  • Chapters
  • descriptions off, selected
  • en (Main), selected
    Video length is 21:45

    Simulink Best Practices for Large-Scale Modeling | Simulink Best Practices for Large-Scale Modeling, Part 1

    From the series: Simulink Best Practices for Large-Scale Modeling

    With systems becoming ever more complex, Simulink® models are getting equally large and complex. Simulink offers the flexibility to create models in multiple ways to suit a wide range of use cases. Some of these modeling patterns are better suited for creating quick and flexible prototypes, while others are better for building and simulating large-scale models. Watch an overview of some of these techniques, which serves as a foundation for deeper videos in this series.

    Published: 7 Jan 2025

    We're going to base our talk today on the activities at a fictional automotive company called Misfire Motors. So their goal is to design and simulate the most sophisticated vehicle in the world. And they gave us this nice marketing slide here that we could use. So there you go. You can take what you want from that.

    Now, these guys started off pretty simple. They started with a simple model that they used to do some development. They quickly found that it was very useful. A lot of their engineers could see the benefit of a modeling approach and a model-based design process. So they quickly started adding more capabilities, and the model grew in size and complexity.

    Unfortunately, though, as they were doing this, they had so much pressure to deliver things on these really tight timelines that they just didn't take the time to put best practices into play. And they suffered several, I would say, challenging issues.

    So the first one from model architecture point of view is they were developing and putting all their content into a single model file. And that thing got gigantic-- hundreds of thousands of blocks in there.

    OK. Second thing, from a data management point of view, is they were putting all their data in the base workspace. All right, and we'll talk more about that in a while. Third, they had interfaces between components in the model that were hard to read and made the model difficult to understand. They had no real file management strategy at all. So that was a big problem for them.

    And finally they suffered from poor simulation performance. Does any of this sound familiar to you guys? Did I see any-- one or more of these? Anybody?

    Yep.

    OK, good. I was afraid you guys were going to say, nope. We got it. We're good.

    [LAUGHTER]

    OK. All right, fair enough. All right, so let's start talking about-- now that we've heard what issues they've faced-- and it sounds like these things are resonating with you guys-- what do we do about them, all right?

    So the first one, the model architecture question, is they just didn't have one. So they started off pretty simple, as I said. And they were putting things into a single model file.

    And they'd had heard about doing componentization with reference models. They looked into it a little bit. But they're like, oh, man, there's different ways of doing it. And we're not sure where we should do this technique or that technique. And they're always under this time pressure that I mentioned, so they decided we're just going to keep doing what we do. They put everything in a single model, right?

    So, Erick, I'm going to turn to you for this one. I know you've done a lot of experience with model architectures discussions at MathWorks. And in your previous experience, what would we advise companies like Misfire Motors to do instead of what they're doing now?

    Hey, Brad. Thanks for introducing us to Misfire Motors and their challenges. So as you already saw, this might be an imaginary company, but these questions and challenges are very real. And hey, we get it. There is no universal answer. The complexity of these models and the requirements cannot be easily summarized in a table like the one I am about to show you.

    However, we have noticed that some components align better with certain use cases. So we want to show you that. By the way, don't worry about taking pictures or making notes of this table. This table, along with this whole slides and an extra set of slides, is going to be available to you at the end of this presentation in what I like to call the director's cut. We only have 20 something minutes, so we can only give you so much right now.

    Anyway, with that out of the way, let's look at some of these use cases. For example, if you want to visually organize a group of blocks or components, we would recommend an in-model vertical subsystem. If you're looking to create utilities that change infrequently and are widely reused, a link subsystem, also known as libraries, is a way to go. And if you're looking to develop or simulate a component as a standalone model, then model reference is the option.

    And speaking of model reference, it is the key to large-scale modeling componentization. There are a few reasons for this. The first is that it enables parallel development because, with Simulink, you can develop your components as independent models. So you will have independent slx file that is fully functional, fully simulatable.

    So in the case of Misfire Motors, these men that their engineers were now able to focus on their own components without worrying about tripping on each other's heels, trying to modify these huge xls file that they had before. And then these models can be placed or, as we say in MathWorks lingo, "referenced," inside other models for easy integration. This enables a few things, and I want to highlight two of them.

    First is the decrease build time when they are reused. So if you have multiple instances of a reference model, it will reduce the build time. And also, it enables the use of accelerator and rapid accelerator modes that Brad is going to explain a little bit later in the performance section. So back to the challenges of Misfire Motors for now.

    Right. So thanks for that, Erick. So that explanation made sense to me, and it made sense to them, so they ended up going and adopting that. So they started componentizing their model.

    And after they were doing that-- well, first, let me back up a second. I want to back up to the second problem with the data management thing. So as I mentioned before, they had put all their data in the base workspace. So when they started out, their model was pretty simple, and they didn't have tons of parameters. So that worked for them.

    But as they started piling more stuff in, they had basically just more and more data accumulating. And they were storing it all in a single file, if you can imagine. And that thing was just getting huge, huge, huge. And it just became untenable.

    So as they were looking around, looking for solutions, they're like, hey, we just listened to Erick. He was telling us about componentizing. We're already doing that. Maybe we should do something like that with our data. And Erick, I know this is front and center for you. You've been doing a lot of this kind of conversations with customers this last few months. What would you recommend for these guys?

    Right. So in this case, I mean, we get it. The base workspace has several use cases. For example, if you're doing informal workflows, quick parameter tuning, rapid prototyping, you have a single developer, or if you need universal visibility of your parameters.

    However, it has some drawbacks. For example, the base workspace is cleared every time that you close your MATLAB session. So you have to save it either in an M script or a dot mat file. And you have to be very intentional about making changes here.

    Usually, we recommend data dictionaries when you want to work with large projects, distributed development, or scoped data. And Misfire Motors had the question-- what is it about these data dictionaries that is so great for large-scale modeling? Well, there are a few things we're going to cover-- three of them right now.

    First, inherit data persistence. Simulink data dictionaries have their own dedicated file format, the dot sldd file. So you do not need to worry about having to save your changes every time. And because this is separate from both the base workspace and the model, it allows for easier data organization.

    So you can partition your data. Instead of having this huge monolithic thing that goes into a single map file, you can partition it into multiple sldds. And then you can make reference to smaller sldds as you need them. This also means that sometimes you might have things like name clashing, where you have two parameters or two signals with the same name in two separate sldds. But the good thing is that you will get warnings, so you can get on top of the situation quickly.

    And lastly, you have change tracking workflows. So you can see the changes. When was the last modification? Who made the last modification? So then you can show revert, diff, and save these changes as you go.

    And the last piece of advice that we had for Misfire Motors is, hey, we get it. Switching from bass workspace to data dictionary seems like a daunting task. You don't have to do it all at once because they can coexist. So you can slowly migrate from the base workspace into these multiple data dictionaries as your project scales up and then stop accessing database workspace completely.

    All right, thanks for that, Erick. So the Misfire Motors engineers, they liked what you were saying and they ended up taking his advice. They componentized their data-- kind of in an analogous way to how they componentize the model structure-- into a collection of Simulink data dictionary files. But after they did that, then they started focusing on the next problem, which is their interfaces that made things hard to read.

    So again, they started off with this big single model. And they decided, well, let's partition it into some virtual subsystems to try to make it a little easier to understand. But what they ended up doing then is interconnecting all these subsystems with just individual signals. And they had literally hundreds of them going in and out. I know this happens a lot, right? And because they did that, it was just hard to read and understand.

    Then they componentised, as Erick was explaining. And they used that same interconnect philosophy, and the model was still hard to understand. So they're like, OK, what do we do now? So Erick, can you help them out?

    Yep. So I like this one because, at least in my mind, this one is easy-- use buses. At a minimum, when they are virtual, buses allow you to combine multiple signals into a single line. So for example, in this case, we have the fault detection component that takes in 11 different signals. But actually, many of them are related, and they are produced by just a handful of components.

    If we look at the first four-- maximum cell voltage, minimum cell voltage, minimum cell temperature, maximum cell temperature-- they are all produced by the same model. So what we could do is package them into a single bus that we can call min_max cells and then feed it to the fault detection component. If we do that with the other three categories of signals, then we will end up with only four buses feeding into our component. And this is much more readable and still conveys most of the information that we need.

    Now, this might look like an oversimplification. You're probably dealing with hundreds instead of dozens of signals. And unfortunately, we do not have the time to go into all the details on how you can address this right now. But for now, back to you, Brad. to hear more about Misfire Motors.

    Right. So again, they like what you're saying. They really trust you by now, right? So they went ahead, changed their interface specs. So they packaged signals into buses. And they thought, yeah, this really helps. It really cleaned it up. So they were pretty happy.

    But-- and there's always a but somewhere in a talk like this-- they followed our directions and componentised. And now they started-- they went from very few files when they started to a whole bunch of files. And as you remember, they didn't have any file management strategy at all.

    So what they would do at the beginning-- again, small number of files-- when they'd make changes, they would add a version number to the file name, or maybe say something like model name underscore final, that kind of thing. People have done-- so this happens, right?

    They just didn't have a way of dealing with all this. And they're looking at us saying, well, you told us to do all this. And now we have all these files. What do we do?

    So I know, Erick, you and I have been talking a lot about this. We've even been doing presentations about it to a few customers. What should they be doing now to fix this?

    Right. So we get it. And fortunately, there's a solution for these MATLAB Projects formerly known as Simulink projects, which will be automating the little things so you guys have the time to focus on the real important stuff. And there are a few ways in which this will happen.

    First when you're choosing a project, it will set up the path for you. And you can also configure the startup and shutdown files so that the environment is always the same every time that you open your project. It also allows you to launch common files whenever you open the project. So if you're always opening the same top level model, you don't need to do that by hand anymore. You can just shove it into the project, and it will happen every time that you open.

    One of my personal favorites is that it allows you to create shortcuts to commonly used tasks that will go into these dedicated Shortcuts tab. So I probably don't need to tell you this. It's not only the sheer number of files that you will have. It's also that you will probably be dealing with a complex folder structure where you have to constantly be looking down three levels to find the file that you need. If you create a shortcut, then you can avoid doing that.

    And projects are also about mistake proofing your work. There are a number of features that help you with this, but I want to highlight just two of them. First, shadowed models and libraries can give you an expected result. So the project will find them and will warn you.

    And I don't know if this has happened to you-- it has definitely happened to me-- that I'm working on a project that has some libraries, some references, and then I get this error about some interfaces not matching. I opened my model. I'm staring at it. Everything matches. So what's going on?

    10, 15 minutes later, I go, I look at the path. And it turns out that there's a model with the exact same name that is just higher in the path hierarchy, and I just wasted some time looking for this. If I was using a project, this would not have happened.

    Next, unsafe changes risk losing work or getting confusing results. the project will always ask you to confirm. Hey, Erick, are you sure that you really want to close me with these unsafe changes? And again, this has happened to me. It's 11:00 PM, the day before the release. I'm tired. I've been working like crazy to make sure that everything works. And it finally did a few minutes ago.

    So I pushed my changes. I close everything. I go to sleep. Next day, I come back. The PM is calling me. Everything is on fire because the results do not match what I did last night. What happened? Well, I was tired and I closed the project, and I closed MATLAB while I had some unsaved changes. And now we have to go about fixing it. With the use of projects, this would be harder to happen. So these are the little things that projects can do that, in the long-term, between you and your whole organization, is going to save you a lot of time.

    And just to close out this topic, I want to say that managing projects-- sorry, managing source control with projects is even easier. So if all you're going to do is your run-of-the-mill operations like refresh, pull, commit, push, or sync the branches, hey, all of that is available to you. In the MATLAB GUI. Of course, you can still use a third party version control tool if you want to do more complex operations. But if you're just doing regular stuff with MATLAB all the time, you have it right where you need it. All right, back to you, Brad.

    Yeah. Thanks, Erick. All right, so these guys at Misfire Motors listened to him, adopted projects, tried it out and said, wow, this is a lot easier than we thought. And they were able to get all of this file management stuff magically under control. So it's really great. In fact, they've taken so much of your advice that I'm surprised they haven't tried to hire you by now. I mean, come on, right?

    OK. So let's move on and talk a little bit about performance. Now, up to now, we've been focusing on best practices that are dealing with structuring your model and your data sets, managing your files, and basically trying to streamline your development process to set yourself up for long-term success. At the same time, though, people want their models to run as fast as possible, initialize as fast as possible. I'm sure you would agree.

    And we often get calls from customers asking us to help with model performance issues that they're having. We have some engineering resources at MathWorks that can help. We've got technical support and application engineering teams. We can meet with customers-- we do this a lot-- analyze the models, look for performance bottlenecks, and make some recommendations to fix them.

    We have a consulting services organization. They can take that much further. They can come up with customized solutions to very challenging performance issues. And another thing they're very good at is once they've come up with these recommendations, they're good at automating the implementation. So sometimes if you have big, large model assemblies, and you have to manually change things, that can be pretty tedious. They can automate that stuff, typically.

    OK. So as I said earlier, the Misfire Motors engineers, when they started off with their original model, it was not too performant. So they instituted all the componentization things. And they noticed initially that, gosh, when the model initialized, it's already a little bit faster after they componentize. And they didn't really understand that, but they wondered why.

    Then they also asked us, well, we still like the thing to simulate faster, so what can we do about it? So let's take a look here in the next few minutes at some typical simulation performance analysis tools and techniques that you can use to address these problems.

    So when we start any typical kind of performance analysis, we'd probably start off with running Performance Advisor. And what that will do is check for model configurations and even modeling patterns that can slow down performance.

    Next, we'd probably run MATLAB Profiler. And what this is good for is if you've got MATLAB code embedded in your model, like callbacks, which most people do, this thing is going to measure how long that code takes to run. And then you can identify hotspots and use that to help your initialization time. Maybe take some time out of that, get it to run faster.

    If you're interested in speeding up your simulation time, we would then use Simulink Profiler, especially if you're using a fixed step solver. And what that does, it's analogous to MATLAB Profiler, except it measures the time it takes Simulink model to execute all the various components, subsystems. And then you can use that information to find hotspots and try to speed up your simulation time.

    If you're using a variable step solver, we would also add in Solver Profiler. What that does is it looks for issues or places in where the simulation is slowing down. It'll identify things that the solver might be doing that are affecting your simulation performance, like, really small time steps. We've seen that a lot, right? Or maybe there's a whole bunch of solver resets happening in different spots. It'll find those and give you suggestions on how to correct them.

    OK. Now, if you're having trouble or, like me, remembering what all these tools are, where they are, when to use them, we've got this Simulink performance guide that we recently developed. And it'll help you-- you think of it as like a cheat sheet. It'll help you start and complete these performance analysis projects. Now, you can get it by scanning that QR code on the slide. And you can come to our booth in the exhibit area. We've got the same thing image up so you can get it there, too. So don't worry about doing it right now.

    A couple of things-- I'd just like to point out two more little features, two more, I should say, not features, but capabilities that you can sometimes use to improve your model initialization time. Doesn't work every time, but I think it's worth mentioning them.

    So when you componentize into reference models-- and I think, Erick, you mentioned that before-- you can use this technique called Accelerator mode, rapid Accelerator mode. So in Accelerator mode, what Simulink will do for that particular component is generate C code and compile it. And we do that so that it'll initialize and simulate faster. So that's a clever thing to do.

    Now, when Simulink does that, it stores that pre-compiled version of that component in a cache file. So cache files can be your friend. You need to definitely look into doing that. When the model initialization stage happens, Simulink's going to scan all the available cache files. And any of those pre-compiled components that are in there that are up-to-date, it's going to just load those very quickly. And any that are out of date, it will rebuild.

    Now, that process we call incremental build. So if you can get to the point where you've minimized the number of rebuild opportunities and maximize the number of A, it's already built and up-to-date, this can have a very big impact on improving your initialization time, but it relies on you having componentized your model.

    And if you remember back when I said the Misfire Motors engineers, the model was componentized, and they went, hey, it's initializing faster. Why is that? It's this. This incremental build is what did it.

    Another thing you can use to speed up initialization time is fast restart. So this is a tool that you can use only under certain conditions. And that is I'm probably going to make-- or if I'm going to make lots of simulation runs in a given MATLAB session, and I'm not going to make any structural changes to the model, just changing data, then I can use this.

    So what it's going to do is, first, the model is going to have to go through its regular initialization time. So you'll pay that price once. So whatever time it normally takes you, it will take here. But the beauty is Simulink will then be able to remember that, that compiled state so that the next time you hit it, it'll start up almost instantly.

    So an example of that, real quick. We had a model that we ran, turned on fast restart. And if you can see the highlight at the top highlighted number, that was the initialization time the first time-- 5.65 seconds if you can't see it in the back. Then we hit Play a second time. The initialization time went to 38 milliseconds. That's what I mean by fast. So under these special circumstances, it's a click of a button. It's very effective

    OK. Now, just to convince you that these techniques, best practices that we've been talking about actually work, here is an example of some performance optimization that our consultant services team did with a real customer model. Not Misfire Motors, but a real-deal model. OK.

    So they use those same performance analysis tools that I talked about at the beginning-- the Matlab Profiler, all that bit? and analyze the customer model, found some opportunities for optimizing. They turned on Accelerator mode in some select locations, were able to optimize the model. And they took the initial models, which you can see in this really tall bar chart. You're probably guessing that.

    It was 160x real-time, slower than real time. After they did some initialization-- or optimizations, I should say, they got it down to that really tiny bar on the right there-- 2.4 times slower than real time. It's a 67 times improvement. It's pretty dramatic. They're not always. Your mileage may vary, of course, but these things do work.