{"id":43,"date":"2009-01-13T22:00:09","date_gmt":"2009-01-13T22:00:09","guid":{"rendered":"https:\/\/blogs.mathworks.com\/seth\/2009\/01\/13\/bus-copies-explained\/"},"modified":"2009-01-14T03:19:56","modified_gmt":"2009-01-14T03:19:56","slug":"bus-copies-explained","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/simulink\/2009\/01\/13\/bus-copies-explained\/","title":{"rendered":"Bus Copies Explained!"},"content":{"rendered":"<p>A Simulink developer caught me in the hall last week and\r\nasked me, \u201cHow do people use the Signal Conversion block?\u201d\u00a0 He was specifically\r\ninterested in how people use <em>Contiguous Copy<\/em> mode, and if people check\r\nthe <em>Override optimizations and always copy signal<\/em> check box.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2009Q1\/sigConvContCopy.png\" alt=\"Signal Conversion block set to contiguous copy mode.\"><\/p>\r\n\r\n<p>If you use the block in your models, <strong>please<\/strong> <a\r\nhref=\"https:\/\/blogs.mathworks.com\/seth\/?p=43&amp;#comment\">post a comment here<\/a>\r\nand tell us about your use case.\u00a0 In this post, I will show you one of the examples\r\nI gave him that has to do with bus copies and unravel some of the interesting\r\nsemantics at work.\u00a0 The models I used are available for <a\r\nhref=\"https:\/\/www.mathworks.com\/matlabcentral\/fileexchange\/22674-bus-copies-explained\">download<\/a>\r\nfrom the File Exchange.<\/p>\r\n\r\n<p><strong>Meaning of Atomic<\/strong><\/p>\r\n\r\n<p>An atomic subsystem is a Simulink semantic that means the\r\nblocks inside execute together, so you can treat them collectively as one block.\u00a0\r\nIt is like a macro or function in C.\u00a0 The routine executes all the code\r\ncontained within and runs to completion.\u00a0 When you draw a line from the output\r\nof a subsystem (A) to another block (B), you are asking for the input to B to\r\nbe the output of A.\u00a0\u00a0 This data dependency ensures that the signal will only change\r\nif that atomic subsystem executes again.\u00a0 If an input to the atomic subsystem\r\nis passes through to the output, unchanged, what happens when that input signal\r\nis changed?\u00a0 Atomic blocks in Simulink must control their output signal memory.\r\nThis gives rise to the following example.<\/p>\r\n\r\n<p><strong>A Signal Runs Through It<\/strong><\/p>\r\n\r\n<p>Here is the NoSignalConversion subsystem.\u00a0 Notice it has a\r\nheavy black outline because the system is atomic.\u00a0 The subsystem takes a bus as\r\ninput, repackages one element from the bus with a computed value and passes it\r\nto the output.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2009Q1\/sigConv1.png\" alt=\"Example atomic subsystem with inport directly passing through to the output.\"><\/p>\r\n\r\n<p>Notice that the diagram is displaying little red numbers on\r\nthe corners of the blocks to indicate their sorted order. Virtual blocks, like\r\nthe bus selector, do not have a place in the sorted order.<\/p>\r\n\r\n<p>When we dive into the subsystem, you can see that the Inport\r\n<em>In1<\/em> has a sorted order label, which means it is non-virtual.\u00a0 Usually\r\nInports are virtual.\u00a0 What does an input port do when it is non-virtual?\u00a0 Let\u2019s\r\nlook at the code:<\/p>\r\n\r\n<pre><em><span style='color:#888888'>\u00a0 109\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0<span class=ct1>\/* Outputs for atomic SubSystem: '<\/span><em><span\r\nstyle='color:#117755'>&lt;Root&gt;\/NoSignalConversion<\/span><\/em><span\r\nclass=ct1>' *\/<\/span><\/pre><pre><em><span style='color:#888888'>\u00a0 110\u00a0\u00a0 <\/span><\/em><\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0\u00a0111\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0<span class=ct1>\/* Inport: '<\/span><em><span\r\nstyle='color:#117755'>&lt;S1&gt;\/In1<\/span><\/em><span class=ct1>' *\/<\/span><\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 112\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0<span class=kw1>for<\/span> (i = 0; i &lt; 6; i++) <strong>{<\/strong><\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 113\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0rtb_In1[i] = rtb_FromWs[i];<\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 114\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0<strong>}<\/strong><\/pre><pre><a name=115><em><span\r\nstyle='color:#888888'>\u00a0 115\u00a0\u00a0 <\/span><\/em><\/a><\/pre><pre><a name=116><em><span\r\nstyle='color:#888888'>\u00a0\u00a0116\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0<span class=ct1>\/* Gain: '<\/span><em><span\r\nstyle='color:#117755'>&lt;S1&gt;\/Gain<\/span><\/em><span class=ct1>' *\/<\/span><\/pre><pre><a\r\nname=117><em><span style='color:#888888'>\u00a0 117\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0rtb_b1 = 2.0 * rtb_In1[1];<\/pre><pre><a\r\nname=118><em><span style='color:#888888'>\u00a0 118\u00a0\u00a0 <\/span><\/em><\/a><\/pre><pre><a\r\nname=119><em><span style='color:#888888'>\u00a0\u00a0119\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0<span\r\nclass=ct1>\/* end of Outputs for SubSystem: '<\/span><em><span\r\nstyle='color:#117755'>&lt;Root&gt;\/NoSignalConversion<\/span><\/em><span\r\nclass=ct1>' *\/<\/span><\/pre><pre><a name=120><em><span style='color:#888888'>\u00a0 120\u00a0\u00a0 <\/span><\/em><\/a><\/pre><pre><a\r\nname=121><em><span style='color:#888888'>\u00a0\u00a0121\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0<span\r\nclass=ct1>\/* Outport: '<\/span><em><span\r\nstyle='color:#117755'>&lt;Root&gt;\/Out1<\/span><\/em><span class=ct1>' *\/<\/span><\/pre><pre><a\r\nname=122><em><span style='color:#888888'>\u00a0 122\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0ssnoSigConv_Y.Out1[0] = rtb_In1[0];<\/pre><pre><a\r\nname=123><em><span style='color:#888888'>\u00a0 123\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0ssnoSigConv_Y.Out1[1] = rtb_b1;<\/pre>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p>It may seem a little cryptic, but the Inport makes a copy of\r\nthe memory outside the atomic subsystem into the subsystem.\u00a0 This copy is the <strong>rtb_In1<\/strong>\r\ntemporary vector (two thirds of this vector is never used!).\u00a0 In this\r\nsituation, the copy is wasteful*, but it happens because of the Simulink semantic\r\nthat all atomic blocks control their output memory.<\/p>\r\n\r\n<p><strong>Signal Conversion Block to the Rescue<\/strong><\/p>\r\n\r\n<p>We can improve our model by inserting a Signal Conversion\r\nBlock.<\/p>\r\n\r\n<p><img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/images\/seth\/2009Q1\/sigConv2.png\" alt=\"Atomic subsystem using a Signal Conversion block to copy the one element that passes through to the output.\"><\/p>\r\n\r\n<p>Inserting the signal conversion block resolves the memory\r\npass through issue.\u00a0 This prevents the Inport from becoming non-virtual, and we\r\nno longer get a copy of all input bus elements.\u00a0 Here is the improved code:<\/p>\r\n\r\n<pre><a name=108><em><span style='color:#888888'>\u00a0 108\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0<span\r\nclass=ct1>\/* Outputs for atomic SubSystem: '<\/span><em><span\r\nstyle='color:#117755'>&lt;Root&gt;\/WithSignalConversion<\/span><\/em><span\r\nclass=ct1>' *\/<\/span><\/pre><pre><a name=109><em><span style='color:#888888'>\u00a0 109\u00a0\u00a0 <\/span><\/em><\/a><\/pre><pre><a\r\nname=110><em><span style='color:#888888'>\u00a0\u00a0110\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0<span\r\nclass=ct1>\/* Gain: '<\/span><em><span\r\nstyle='color:#117755'>&lt;S2&gt;\/Gain<\/span><\/em><span class=ct1>' *\/<\/span><\/pre><pre><a\r\nname=111><em><span style='color:#888888'>\u00a0 111\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0rtb_b1 = 2.0 * rtb_FromWs[1];<\/pre><pre><a\r\nname=112><em><span style='color:#888888'>\u00a0 112\u00a0\u00a0 <\/span><\/em><\/a><\/pre><pre><a\r\nname=113><em><span style='color:#888888'>\u00a0\u00a0113\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0<span\r\nclass=ct1>\/* SignalConversion: '&lt;S2&gt;\/TmpHiddenBufferAtSignal ConversionInport1' *\/<\/span><\/pre><pre><a\r\nname=114><em><span style='color:#888888'>\u00a0 114\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0\u00a0\u00a0rtb_TmpHiddenBufferAtSignalConv = rtb_FromWs[0];<\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 115\u00a0\u00a0 <\/span><\/em><\/pre><pre><em><span style='color:#888888'>\u00a0\u00a0116\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0<span\r\nclass=ct1>\/* end of Outputs for SubSystem: '<\/span><em><span\r\nstyle='color:#117755'>&lt;Root&gt;\/WithSignalConversion<\/span><\/em><span\r\nclass=ct1>' *\/<\/span><\/pre><pre><em><span style='color:#888888'>\u00a0 117\u00a0\u00a0 <\/span><\/em><\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0\u00a0118\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0<span class=ct1>\/* Outport: '<\/span><em><span\r\nstyle='color:#117755'>&lt;Root&gt;\/Out<\/span><\/em><span class=ct1>' *\/<\/span><\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 119\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0sswSigConv_Y.Out[0] = rtb_TmpHiddenBufferAtSignalConv;<\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 120\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0\u00a0\u00a0sswSigConv_Y.Out[1] = rtb_b1;<\/pre>\r\n\r\n<p>&nbsp;<\/p>\r\n\r\n<p><strong>Important Code Efficiency Note:<\/strong> If you enable the <em>Eliminate\r\nsuperfluous local variables (Expression folding)<\/em> optimization, both\r\nsubsystems produce roughly identical code that looks like this:<\/p>\r\n\r\n<pre><a name=105><em><span style='color:#888888'>\u00a0 105\u00a0\u00a0 <\/span><\/em><\/a>\u00a0\u00a0<span\r\nclass=ct1>\/* Outport: '<\/span><em><span\r\nstyle='color:#117755'>&lt;Root&gt;\/Out1<\/span><\/em><span class=ct1>' incorporates:<\/span><\/pre><pre><a\r\nname=106><em><span style='color:#888888'>\u00a0 106\u00a0\u00a0 <\/span><\/em><\/a><span class=ct1>\u00a0\u00a0\u00a0*\u00a0 Gain: '<\/span><em><span\r\nstyle='color:#117755'>&lt;S1&gt;\/Gain<\/span><\/em><span class=ct1>'<\/span><\/pre><pre><a\r\nname=107><em><span style='color:#888888'>\u00a0 107\u00a0\u00a0 <\/span><\/em><\/a><span class=ct1>\u00a0\u00a0\u00a0*\u00a0 Inport: '<\/span><em><span\r\nstyle='color:#117755'>&lt;S1&gt;\/In1<\/span><\/em><span class=ct1>'<\/span><\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 108\u00a0\u00a0 <\/span><\/em><span class=ct1>\u00a0\u00a0\u00a0*\/<\/span><\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 109\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0ssnoSigConvExprFld_Y.Out1[0] = rtb_FromWs[0];<\/pre><pre><em><span\r\nstyle='color:#888888'>\u00a0 110\u00a0\u00a0 <\/span><\/em>\u00a0\u00a0ssnoSigConvExprFld_Y.Out1[1] = 2.0 * rtb_FromWs[1];<\/pre><pre>&nbsp;<\/pre>\r\n\r\n<p><strong>Interesting Semantics at Work<\/strong><\/p>\r\n\r\n<p>This is not the first time I have had to explain this\r\ninteresting interaction of semantics.\u00a0 Technical support will occasionally get\r\ncalls asking why the generated code includes unnecessary bus data copies.\u00a0 We\r\neven wrote a <a\r\nhref=\"https:\/\/www.mathworks.com\/support\/solutions\/data\/1-1RPS3Z.html?solution=1-1RPS3Z\">technical\r\nsupport solution<\/a> that explains this exact phenomenon.\u00a0 Here is the summary\r\nof what is happening:<\/p>\r\n\r\n<p class=MsoQuote>Simulink requires that atomic subsystems own the memory they\r\noutput. In part, this defines the system as an atomic unit. Hence, all outputs\r\nmust originate from blocks inside the atomic subsystem. When an input port\r\nfeeds its signal directly to an output port in the atomic subsystem, the input\r\nport becomes nonvirtual and makes a copy of its input signal. When passing bus\r\nsignals through atomic subsystems, this rule still applies, and the result is\r\noften perceived as unnecessary copies of bus signals in the generated code.<\/p>\r\n\r\n<p><strong>We want your feedback!<\/strong><\/p>\r\n\r\n<p>This is only one instance of bus signal copies.\u00a0 What other modeling\r\nconstructs do you want to learn?\u00a0 How do you use the signal conversion block?\u00a0\r\nDo you use the \u201cOverride optimizations and always copy signal\u201d check box?\u00a0\r\nShare your use case and leave a <a\r\nhref=\"https:\/\/blogs.mathworks.com\/seth\/?p=43&amp;#comment\">comment here<\/a>.<\/p>\r\n","protected":false},"excerpt":{"rendered":"<p>A Simulink developer caught me in the hall last week and\r\nasked me, \u201cHow do people use the Signal Conversion block?\u201d\u00a0 He was specifically\r\ninterested in how people use Contiguous Copy mode, and if... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/simulink\/2009\/01\/13\/bus-copies-explained\/\">read more >><\/a><\/p>","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[21,11,33],"tags":[12,441],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/43"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/users\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/comments?post=43"}],"version-history":[{"count":0,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/posts\/43\/revisions"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/media?parent=43"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/categories?post=43"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/simulink\/wp-json\/wp\/v2\/tags?post=43"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}