{"id":9692,"date":"2018-05-04T08:50:09","date_gmt":"2018-05-04T12:50:09","guid":{"rendered":"https:\/\/blogs.mathworks.com\/pick\/?p=9692"},"modified":"2018-05-04T09:20:22","modified_gmt":"2018-05-04T13:20:22","slug":"persistent-data-for-lookup-tables-in-simulink","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/pick\/2018\/05\/04\/persistent-data-for-lookup-tables-in-simulink\/","title":{"rendered":"Persistent Data for Lookup Tables in Simulink"},"content":{"rendered":"<div xmlns:mwsh=\"https:\/\/www.mathworks.com\/\/namespace\/mcode\/v1\/syntaxhighlight.dtd\" class=\"content\">\n   <introduction><\/p>\n<p><i>Richard is a Consultant at MathWorks focused on Model Based Design, primarily in the Aerospace and Defense industry.<\/i><\/p>\n<p><a href=\"https:\/\/www.mathworks.com\/\/matlabcentral\/profile\/authors\/1016860-richard-ruff\">Richard&#8217;s<\/a> pick this week is <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/67163-persistent-data-for-lookup-tables-in-simulink\">Persistent Data for Lookup Tables in Simulink<\/a> by <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/733182-jason-nicholson\">Jason Nicholson<\/a>.\n      <\/p>\n<p>   <\/introduction><\/p>\n<h3>Pick<a name=\"1\"><\/a><\/h3>\n<p>My pick this week is <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/67163-persistent-data-for-lookup-tables-in-simulink\">Persistent Data for Lookup Tables in Simulink<\/a> &#8211; a method to speed up simulations that use large lookup tables.\n   <\/p>\n<p>As systems become more and more complex, the need for simulation increases.  Simulation provides insight into the behavior<br \/>\n      and performance of the system.  However, as systems become more complex, the level of fidelity needed in a simulation also<br \/>\n      increases, which often increases the time it takes for the simulation to run.  This in turn slows the development process.\n   <\/p>\n<p>Persistent Data for Lookup Tables in Simulink addresses a specific issue related to simulation performance &#8211; as noted in the<br \/>\n      File Exchange entry: <i>&#8220;Loading large lookup tables in Simulink models can be the bottle neck for the simulation speed. This is more important when<br \/>\n         you cannot load a lookup table into the base workspace or model workspace when you build a Simulink library. When you don&#8217;t<br \/>\n         know how the library will be used, loading data into the base or model workspace can cause problems and thus it is bad practice<br \/>\n         to do so. This set of files shows how to load a lookup table in the mask initialization of a subsystem block and then save<br \/>\n         it to UserData. On subsequent runs, the data stored in UserData is used for the lookup table. The speed up is 10-50x.&#8221;<\/i><\/p>\n<p><img decoding=\"async\" vspace=\"5\" hspace=\"5\" src=\"https:\/\/blogs.mathworks.com\/images\/pick\/Sean\/main_PersistentDataInSimulink\/mask.png\"> <\/p>\n<p>It should be noted that this approach is only valid when running multiple simulations of a Simulink model.<\/p>\n<p>The download from the File Exchange contains two Simulink models, a Simulink library containing the two implementations of<br \/>\n      the masked Lookup Table block (with and without persistent data), and a script that describes the application.\n   <\/p>\n<p>To test this, I extracted and ran the simulation execution code provided in <tt>RunSimulations<\/tt>.\n   <\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">\r\nNUMBER_OF_TIMING_RUNS = 10;\r\nRUN_MODES = {<span style=\"color: #A020F0\">'Normal'<\/span>, <span style=\"color: #A020F0\">'Accelerator'<\/span>};\r\nMODEL_1 = <span style=\"color: #A020F0\">'withoutPersistentLoading'<\/span>;\r\nMODEL_2 = <span style=\"color: #A020F0\">'withPersistentLoading'<\/span>;\r\nmodels = {MODEL_1, MODEL_2};\r\n\r\n<span style=\"color: #228B22\">% models = {'FastRestartTest'};<\/span>\r\n\r\n<span style=\"color: #228B22\">% loop over the run modes<\/span>\r\n<span style=\"color: #0000FF\">for<\/span> iMode = 1:length(RUN_MODES)\r\n    <span style=\"color: #0000FF\">for<\/span> iModel = 1:length(models)\r\n        memoryBeforeRun = nan(NUMBER_OF_TIMING_RUNS, 1);\r\n        memoryAfterRun = nan(NUMBER_OF_TIMING_RUNS, 1);\r\n        load_system(models{iModel});\r\n        <span style=\"color: #0000FF\">for<\/span> iSim = 1:NUMBER_OF_TIMING_RUNS\r\n            memoryBeforeRun(iSim) = getfield(memory, <span style=\"color: #A020F0\">'MemUsedMATLAB'<\/span>)\/1024^2;\r\n            simOut = sim(models{iModel}, <span style=\"color: #A020F0\">'SimulationMode'<\/span>, RUN_MODES{iMode});\r\n            <span style=\"color: #0000FF\">if<\/span> iSim == 1\r\n                TimingInfo = simOut.SimulationMetadata.TimingInfo;\r\n            <span style=\"color: #0000FF\">else<\/span>\r\n                TimingInfo(iSim) = simOut.SimulationMetadata.TimingInfo;\r\n            <span style=\"color: #0000FF\">end<\/span>\r\n            memoryAfterRun(iSim) = getfield(memory, <span style=\"color: #A020F0\">'MemUsedMATLAB'<\/span>)\/1024^2;\r\n        <span style=\"color: #0000FF\">end<\/span>\r\n        close_system(models{iModel});\r\n        \r\n        fprintf(<span style=\"color: #A020F0\">'Model \"%s\", in \"%s\" mode:\\n'<\/span>, models{iModel}, RUN_MODES{iMode})\r\n        outputTable = table(memoryBeforeRun, memoryAfterRun, <span style=\"color: #0000FF\">...<\/span>\r\n            vertcat(TimingInfo.InitializationElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n            vertcat(TimingInfo.ExecutionElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n            vertcat(TimingInfo.TerminationElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n            vertcat(TimingInfo.TotalElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n            <span style=\"color: #A020F0\">'VariableNames'<\/span>, <span style=\"color: #0000FF\">...<\/span>\r\n            {<span style=\"color: #A020F0\">'memoryBefore'<\/span>, <span style=\"color: #A020F0\">'memoryAfter'<\/span>, <span style=\"color: #A020F0\">'initializationTime'<\/span>, <span style=\"color: #0000FF\">...<\/span>\r\n            <span style=\"color: #A020F0\">'executionTime'<\/span>, <span style=\"color: #A020F0\">'terminationTime'<\/span>, <span style=\"color: #A020F0\">'totalElapsedTime'<\/span>});\r\n        outputTable.Properties.VariableUnits = {<span style=\"color: #A020F0\">'MB'<\/span>, <span style=\"color: #A020F0\">'MB'<\/span>, <span style=\"color: #A020F0\">'sec'<\/span>, <span style=\"color: #A020F0\">'sec'<\/span>, <span style=\"color: #A020F0\">'sec'<\/span>,<span style=\"color: #A020F0\">'sec'<\/span>};\r\n        disp(outputTable)\r\n        fprintf(<span style=\"color: #A020F0\">'mean Initialization time = %g\\n'<\/span>, mean(outputTable.initializationTime));\r\n        fprintf(<span style=\"color: #A020F0\">'mean Total Elapsed time = %g\\n'<\/span>, mean(outputTable.totalElapsedTime));\r\n        fprintf(<span style=\"color: #A020F0\">'subsequent runs mean Initialization time = %g\\n'<\/span>, mean(outputTable.initializationTime(2:end)));\r\n        fprintf(<span style=\"color: #A020F0\">'subsequent runs mean Total Elapsed time = %g\\n'<\/span>, mean(outputTable.totalElapsedTime(2:end)));\r\n        fprintf(<span style=\"color: #A020F0\">'\\n\\n\\n'<\/span>);\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n<span style=\"color: #0000FF\">end<\/span>\r\n<\/pre>\n<p>The results are:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">RunSimulations<\/pre>\n<pre style=\"font-style:oblique\">Model \"withoutPersistentLoading\", in \"Normal\" mode:\r\n    memoryBefore    memoryAfter    initializationTime    executionTime    terminationTime    totalElapsedTime\r\n    ____________    ___________    __________________    _____________    _______________    ________________\r\n       3972.2         3972.3             3.6936            0.000501          0.003477             3.6976     \r\n       3972.3         3972.3             3.6783            0.000385          0.002951             3.6817     \r\n       3972.3         3972.3             3.5621                   0           0.00351             3.5656     \r\n       3972.3         3972.2             3.5239                   0          0.003008             3.5269     \r\n       3972.2         3972.2             3.5635              0.0005          0.002925             3.5669     \r\n       3972.2         3972.2             3.5189              0.0005          0.003007             3.5224     \r\n       3972.2         3972.2             3.6783            0.000869          0.003016             3.6822     \r\n       3972.2         3972.2             4.2864                   0           0.00401             4.2904     \r\n       3972.2         3972.2             4.0488            0.000502          0.003008             4.0523     \r\n       3972.2         3972.2             4.0197            0.000501          0.003009             4.0232     \r\nmean Initialization time = 3.75736\r\nmean Total Elapsed time = 3.76093\r\nsubsequent runs mean Initialization time = 3.76444\r\nsubsequent runs mean Total Elapsed time = 3.76797\r\n\r\n\r\n\r\nModel \"withPersistentLoading\", in \"Normal\" mode:\r\n    memoryBefore    memoryAfter    initializationTime    executionTime    terminationTime    totalElapsedTime\r\n    ____________    ___________    __________________    _____________    _______________    ________________\r\n       3081.1         3972.1              3.4181           0.000494          0.003146              3.4217    \r\n       3972.1         3097.5             0.16842           0.001027          0.003958              0.1734    \r\n       3097.5         3097.5            0.053643                  0          0.003551            0.057194    \r\n       3097.5         3097.5            0.053183           0.000785           0.00251            0.056478    \r\n       3097.5         3097.5            0.053181           0.000463          0.003542            0.057186    \r\n       3097.5         3097.5            0.053642                  0          0.003364            0.057006    \r\n       3097.5         3097.5            0.055127           0.000463          0.003007            0.058597    \r\n       3097.5         3097.5            0.055593           0.000503          0.003005            0.059101    \r\n       3097.5         3097.5            0.051575           0.000501          0.003099            0.055175    \r\n       3097.5         3097.5            0.054585                  0           0.00305            0.057635    \r\nmean Initialization time = 0.401701\r\nmean Total Elapsed time = 0.405348\r\nsubsequent runs mean Initialization time = 0.0665499\r\nsubsequent runs mean Total Elapsed time = 0.0701974\r\n\r\n\r\n\r\nModel \"withoutPersistentLoading\", in \"Accelerator\" mode:\r\n    memoryBefore    memoryAfter    initializationTime    executionTime    terminationTime    totalElapsedTime\r\n    ____________    ___________    __________________    _____________    _______________    ________________\r\n       3081.1         3972.2             3.4136            0.000433          0.004012             3.4181     \r\n       3972.2         3972.2              3.479            0.000351           0.00447             3.4839     \r\n       3972.2         3972.2             3.5448            0.000357          0.004129             3.5493     \r\n       3972.2         3972.2             3.5329              0.0005           0.00401             3.5374     \r\n       3972.2         3972.2              3.584            0.000828          0.004224             3.5891     \r\n       3972.2         3972.2             3.5119            0.000367          0.004014             3.5163     \r\n       3972.2         3972.2             3.6458            0.000499           0.00438             3.6506     \r\n       3972.2         3972.2             3.5952            0.000969           0.00513             3.6013     \r\n       3972.2         3972.2             3.5499              0.0005          0.004259             3.5547     \r\n       3972.2         3972.2             4.6684            0.000501          0.009526             4.6784     \r\nmean Initialization time = 3.65256\r\nmean Total Elapsed time = 3.65791\r\nsubsequent runs mean Initialization time = 3.67911\r\nsubsequent runs mean Total Elapsed time = 3.68456\r\n\r\n\r\n\r\nModel \"withPersistentLoading\", in \"Accelerator\" mode:\r\n    memoryBefore    memoryAfter    initializationTime    executionTime    terminationTime    totalElapsedTime\r\n    ____________    ___________    __________________    _____________    _______________    ________________\r\n         3081         3972.2              4.0312           0.000501          0.004511             4.0362     \r\n       3972.2         3097.5             0.21853           0.000501          0.004513            0.22354     \r\n       3097.5         3097.5            0.098708           0.000501           0.00401            0.10322     \r\n       3097.5         3097.5             0.10075           0.000462           0.00437            0.10558     \r\n       3097.5         3097.5             0.10271           0.000502          0.004011            0.10723     \r\n       3097.5         3097.5             0.10353           0.000356           0.00429            0.10818     \r\n       3097.5         3097.5            0.099265           0.000896          0.004016            0.10418     \r\n       3097.5         3097.5             0.11075                  0          0.004832            0.11559     \r\n       3097.5         3097.5             0.10829                  0          0.006519            0.11481     \r\n       3097.5         3097.5             0.11425           0.000497          0.005016            0.11976     \r\nmean Initialization time = 0.508801\r\nmean Total Elapsed time = 0.513832\r\nsubsequent runs mean Initialization time = 0.117421\r\nsubsequent runs mean Total Elapsed time = 0.122453\r\n\r\n\r\n\r\n<\/pre>\n<p>As can be seen in the results, the model without the persistent data takes about 2.8 seconds to run each simulation.  Running<br \/>\n      it in Accelerator mode increases the time slightly to around 2.9 seconds.  If we run the model with persistent data, the first<br \/>\n      iteration takes a little more time than the simulations without persistent data, about 3.0 seconds. However, subsequent runs<br \/>\n      with persistent data show a drastic improvement, running in a little over 0.5 seconds.  Similar to the runs without persistent<br \/>\n      data, the runs in Accelerator mode took slightly longer.  This additional time is caused by having to verify the Accelerator<br \/>\n      mode version is up to date and no changes have been made to the model between runs.\n   <\/p>\n<p>I was also curious to see how Jason&#8217;s solution would compare with the built-in capability <a href=\"https:\/\/www.mathworks.com\/help\/simulink\/ug\/fast-restart-workflow.html\">Fast Restart<\/a>.  I modified the code used to generate the previous results to run the model without persistent data using Fast Restart.<br \/>\n       Here&#8217;s the code for <tt>RunFastRestart<\/tt>.\n   <\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">\r\nNUMBER_OF_TIMING_RUNS = 10;\r\n\r\nmemoryBeforeRun = nan(NUMBER_OF_TIMING_RUNS, 1);\r\nmemoryAfterRun = nan(NUMBER_OF_TIMING_RUNS, 1);\r\nload_system(models{iModel});\r\n<span style=\"color: #0000FF\">for<\/span> iSim = 1:NUMBER_OF_TIMING_RUNS\r\n    memoryBeforeRun(iSim) = getfield(memory, <span style=\"color: #A020F0\">'MemUsedMATLAB'<\/span>)\/1024^2;\r\n    simOut = sim(<span style=\"color: #A020F0\">'withoutPersistentLoading'<\/span>,  <span style=\"color: #A020F0\">'FastRestart'<\/span>, <span style=\"color: #A020F0\">'on'<\/span>);\r\n    <span style=\"color: #0000FF\">if<\/span> iSim == 1\r\n        TimingInfo = simOut.SimulationMetadata.TimingInfo;\r\n    <span style=\"color: #0000FF\">else<\/span>\r\n        TimingInfo(iSim) = simOut.SimulationMetadata.TimingInfo;\r\n    <span style=\"color: #0000FF\">end<\/span>\r\n    memoryAfterRun(iSim) = getfield(memory, <span style=\"color: #A020F0\">'MemUsedMATLAB'<\/span>)\/1024^2;\r\n<span style=\"color: #0000FF\">end<\/span>\r\nset_param(gcs, <span style=\"color: #A020F0\">'FastRestart'<\/span>, <span style=\"color: #A020F0\">'off'<\/span>);\r\nclose_system(models{iModel});\r\n\r\nfprintf(<span style=\"color: #A020F0\">'Model \"%s\", using FastRestart\\n'<\/span>, models{iModel})\r\noutputTable = table(memoryBeforeRun, memoryAfterRun, <span style=\"color: #0000FF\">...<\/span>\r\n    vertcat(TimingInfo.InitializationElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n    vertcat(TimingInfo.ExecutionElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n    vertcat(TimingInfo.TerminationElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n    vertcat(TimingInfo.TotalElapsedWallTime), <span style=\"color: #0000FF\">...<\/span>\r\n    <span style=\"color: #A020F0\">'VariableNames'<\/span>, <span style=\"color: #0000FF\">...<\/span>\r\n    {<span style=\"color: #A020F0\">'memoryBefore'<\/span>, <span style=\"color: #A020F0\">'memoryAfter'<\/span>, <span style=\"color: #A020F0\">'initializationTime'<\/span>, <span style=\"color: #0000FF\">...<\/span>\r\n    <span style=\"color: #A020F0\">'executionTime'<\/span>, <span style=\"color: #A020F0\">'terminationTime'<\/span>, <span style=\"color: #A020F0\">'totalElapsedTime'<\/span>});\r\noutputTable.Properties.VariableUnits = {<span style=\"color: #A020F0\">'MB'<\/span>, <span style=\"color: #A020F0\">'MB'<\/span>, <span style=\"color: #A020F0\">'sec'<\/span>, <span style=\"color: #A020F0\">'sec'<\/span>, <span style=\"color: #A020F0\">'sec'<\/span>,<span style=\"color: #A020F0\">'sec'<\/span>};\r\ndisp(outputTable)\r\nfprintf(<span style=\"color: #A020F0\">'mean Initialization time = %g\\n'<\/span>, mean(outputTable.initializationTime));\r\nfprintf(<span style=\"color: #A020F0\">'mean Total Elapsed time = %g\\n'<\/span>, mean(outputTable.totalElapsedTime));\r\nfprintf(<span style=\"color: #A020F0\">'subsequent runs mean Initialization time = %g\\n'<\/span>, mean(outputTable.initializationTime(2:end)));\r\nfprintf(<span style=\"color: #A020F0\">'subsequent runs mean Total Elapsed time = %g\\n'<\/span>, mean(outputTable.totalElapsedTime(2:end)));\r\n\r\n<\/pre>\n<p>The results are:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid rgb(200,200,200)\">RunFastRestart<\/pre>\n<pre style=\"font-style:oblique\">Model \"withPersistentLoading\", using FastRestart\r\n    memoryBefore    memoryAfter    initializationTime    executionTime    terminationTime    totalElapsedTime\r\n    ____________    ___________    __________________    _____________    _______________    ________________\r\n         3081         3988.5               3.513           0.000502          0.003007              3.5165    \r\n       3988.5         3988.5            0.020555           0.000501          0.002004             0.02306    \r\n       3988.5         3988.5            0.018047                  0          0.002006            0.020053    \r\n       3988.5         3988.5            0.017049           0.000497          0.002035            0.019581    \r\n       3988.5         3988.5            0.016983           0.000711          0.001507            0.019201    \r\n       3988.5         3988.5            0.017546                  0          0.002065            0.019611    \r\n       3988.5         3988.5            0.018549                  0          0.002006            0.020555    \r\n       3988.5         3988.5            0.020056                  0          0.002465            0.022521    \r\n       3988.5         3988.5            0.018049                  0          0.002006            0.020055    \r\n       3988.5         3988.5            0.018042             0.0005          0.001923            0.020465    \r\nmean Initialization time = 0.367784\r\nmean Total Elapsed time = 0.370157\r\nsubsequent runs mean Initialization time = 0.0183196\r\nsubsequent runs mean Total Elapsed time = 0.0205669\r\n<\/pre>\n<p>As you can see, using Fast Restart actually improved the overall performance of the simulation runs with an average run time<br \/>\n      around 0.018 seconds.  The first run using Fast Restart still requires the loading of the data and this can be seen in the<br \/>\n      execution time being very similar to the first simulation run without persistent data in normal mode shown previously.\n   <\/p>\n<h3>Comments<a name=\"4\"><\/a><\/h3>\n<p>As shown in the results, the speed up in simulation time using this method only applies to subsequent runs, as the first simulation<br \/>\n      will still encounter the bottle neck associated with loading the data the first time.  Furthermore, the results show that<br \/>\n      using FastRestart provides some improvement in these simple cases but I would expect even better performance for larger and<br \/>\n      more complex models.  The advantage of Fast restart is that it doesn&#8217;t require the user to create custom masks for blocks<br \/>\n      and their associated initialization code and it is applied to the entire model.  However, FastRestart is not a valid approach<br \/>\n      if you are using an older version of MATLAB (prior to R2014B release) or if you require running in Accelerator mode.  It is<br \/>\n      nice to know this approach is available if needed.\n   <\/p>\n<p>All in all, this is a great example of how to leverage functionality in Simulink to eliminate a bottle neck in simulation<br \/>\n      execution time.  Give it a try and let us know what you think <a href=\"https:\/\/blogs.mathworks.com\/pick\/?p=9692#respond\">here<\/a> or leave a message for <a href=\"https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/733182-jason-nicholson\">Jason<\/a>.\n   <\/p>\n<p><script language=\"JavaScript\">\n<!--\n\n    function grabCode_6913c7c1b55b449eabbf80ecc26946b6() {\n        \/\/ Remember the title so we can use it in the new page\n        title = document.title;\n\n        \/\/ Break up these strings so that their presence\n        \/\/ in the Javascript doesn't mess up the search for\n        \/\/ the MATLAB code.\n        t1='6913c7c1b55b449eabbf80ecc26946b6 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 6913c7c1b55b449eabbf80ecc26946b6';\n    \n        b=document.getElementsByTagName('body')[0];\n        i1=b.innerHTML.indexOf(t1)+t1.length;\n        i2=b.innerHTML.indexOf(t2);\n \n        code_string = b.innerHTML.substring(i1, i2);\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\n\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \n        \/\/ in the XML parser.\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\n        \/\/ doesn't go ahead and substitute the less-than character. \n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\n\n        author = 'Richard Ruff';\n        copyright = 'Copyright 2018 The MathWorks, Inc.';\n\n        w = window.open();\n        d = w.document;\n        d.write('\n\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\n\n\\n');\n      \n      d.title = title + ' (MATLAB code)';\n      d.close();\n      }   \n      \n-->\n<\/script><\/p>\n<p style=\"text-align: right; font-size: xx-small; font-weight:lighter;   font-style: italic; color: gray\"><a href=\"javascript:grabCode_6913c7c1b55b449eabbf80ecc26946b6()\"><span style=\"font-size: x-small;        font-style: italic;\">Get<br \/>\n            the MATLAB code<br \/>\n            <noscript>(requires JavaScript)<\/noscript><\/span><\/a><\/p>\n<p>      Published with MATLAB&reg; R2018a<\/p>\n<\/div>\n<p><!--\n6913c7c1b55b449eabbf80ecc26946b6 ##### SOURCE BEGIN #####\n%% Persistent Data for Lookup Tables in Simulink\n%\n% Posted by *Richard Ruff* , May 4, 2018\n%\n% _Richard is a Consultant at MathWorks focused on Model Based Design,\n% primarily in the Aerospace and Defense industry._\n% \n% <https:\/\/www.mathworks.com\/\/matlabcentral\/profile\/authors\/1016860-richard-ruff\n% Richard's> pick this week is\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/67163-persistent-data-for-lookup-tables-in-simulink\n% Persistent Data for Lookup Tables in Simulink> by\n% <https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/733182-jason-nicholson\n% Jason Nicholson>.\n% \n%% Pick\n% My pick this week is\n% <https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/67163-persistent-data-for-lookup-tables-in-simulink\n% Persistent Data for Lookup Tables in Simulink> - a method to speed up\n% simulations that use large lookup tables.\n%\n% As systems become more and more complex, the need for simulation\n% increases.  Simulation provides insight into the behavior and performance\n% of the system.  However, as systems become more complex, the level of\n% fidelity needed in a simulation also increases, which often increases the\n% time it takes for the simulation to run.  This in turn slows the\n% development process.\n%\n% Persistent Data for Lookup Tables in Simulink addresses a specific issue\n% related to simulation performance - as noted in the File Exchange entry:\n% _\"Loading large lookup tables in Simulink models can be the bottle neck\n% for the simulation speed. This is more important when you cannot load a\n% lookup table into the base workspace or model workspace when you build a\n% Simulink library. When you don't know how the library will be used,\n% loading data into the base or model workspace can cause problems and thus\n% it is bad practice to do so. This set of files shows how to load a lookup\n% table in the mask initialization of a subsystem block and then save it to\n% UserData. On subsequent runs, the data stored in UserData is used for the\n% lookup table. The speed up is 10-50x.\"_\n%\n% <<mask.png>>\n%\n% It should be noted that this approach is only valid when running multiple\n% simulations of a Simulink model.\n%\n% The download from the File Exchange contains two Simulink models, a\n% Simulink library containing the two implementations of the masked Lookup\n% Table block (with and without persistent data), and a script that\n% describes the application.\n%\n% To test this, I extracted and ran the simulation execution code provided\n% in |RunSimulations|.\n%\n% <include>RunSimulations<\/include>\n%\n% The results are:\n\nRunSimulations\n\n%%\n% As can be seen in the results, the model without the persistent data\n% takes about 2.8 seconds to run each simulation.  Running it in\n% Accelerator mode increases the time slightly to around 2.9\n% seconds.  If we run the model with persistent data, the first iteration\n% takes a little more time than the simulations without persistent data,\n% about 3.0 seconds. However, subsequent runs with persistent data show a\n% drastic improvement, running in a little over 0.5 seconds.  Similar to the\n% runs without persistent data, the runs in Accelerator mode took slightly\n% longer.  This additional time is caused by having to verify the\n% Accelerator mode version is up to date and no changes have been made to\n% the model between runs.\n%\n% I was also curious to see how Jason's solution would compare with the\n% built-in capability\n% <https:\/\/www.mathworks.com\/help\/simulink\/ug\/fast-restart-workflow.html\n% Fast Restart>.  I modified the code used to generate the previous results\n% to run the model without persistent data using Fast Restart.  Here's the\n% code for |RunFastRestart|.\n%\n% <include>RunFastRestart<\/include>\n%\n% The results are:\n\nRunFastRestart\n\n%%\n% As you can see, using Fast Restart actually improved the overall\n% performance of the simulation runs with an average run time around 0.018\n% seconds.  The first run using Fast Restart still requires the loading of\n% the data and this can be seen in the execution time being very similar to\n% the first simulation run without persistent data in normal mode shown\n% previously.  \n%\n%% Comments\n% As shown in the results, the speed up in simulation time using this\n% method only applies to subsequent runs, as the first simulation will\n% still encounter the bottle neck associated with loading the data the\n% first time.  Furthermore, the results show that using FastRestart\n% provides some improvement in these simple cases but I would expect even\n% better performance for larger and more complex models.  The advantage\n% of Fast restart is that it doesn't require the user to create custom\n% masks for blocks and their associated initialization code and it is\n% applied to the entire model.  However, FastRestart is not a valid\n% approach if you are using an older version of MATLAB (prior to R2014B\n% release) or if you require running in Accelerator mode.  It is nice to\n% know this approach is available if needed.\n% \n% All in all, this is a great example of how to leverage functionality in\n% Simulink to eliminate a bottle neck in simulation execution time.  Give it a\n% try and let us know what you think\n% <https:\/\/blogs.mathworks.com\/pick\/?p=9692#respond here> or leave a message\n% for\n% <https:\/\/www.mathworks.com\/matlabcentral\/profile\/authors\/733182-jason-nicholson\n% Jason>.\n%\n \n\n##### SOURCE END ##### 6913c7c1b55b449eabbf80ecc26946b6\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/images\/pick\/Sean\/main_PersistentDataInSimulink\/mask.png\" onError=\"this.style.display ='none';\" \/><\/div>\n<p>Richard is a Consultant at MathWorks focused on Model Based Design, primarily in the Aerospace and Defense industry.<br \/>\nRichard&#8217;s pick this week is Persistent Data for Lookup Tables in&#8230; <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/pick\/2018\/05\/04\/persistent-data-for-lookup-tables-in-simulink\/\">read more >><\/a><\/p>\n","protected":false},"author":131,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/9692"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/users\/131"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/comments?post=9692"}],"version-history":[{"count":4,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/9692\/revisions"}],"predecessor-version":[{"id":9698,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/posts\/9692\/revisions\/9698"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/media?parent=9692"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/categories?post=9692"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/pick\/wp-json\/wp\/v2\/tags?post=9692"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}