Task-Based Sorting to Determine Block Execution Order

Overview

Task-based sorting sets the execution order of blocks and ports based on their derived sample time information. It enhances block sorting by providing a more efficient and simpler process for determining the execution order of blocks.

With task-based sorting:

  • Tasks are sorted based on sample time individually.

  • Multiple sorted lists are generated instead of one flattened sorted list of blocks across all tasks.

  • Rate transition handling is simplified.

  • False data dependency violations are avoided involving blocks in different tasks.

  • Code generation results are in more efficient rate groupings.

  • One subsystem can belong multiple sorted lists.

An API provides the ability to get detailed information of task-based sorted lists. An Update Advisor check address any behavior change between task-base sorting and block sorting.

Execution Order Viewer

The Execution Order viewer displays a list of tasks. Selecting a task displays the execution order for blocks belonging to the task.

  1. From the Debug tab and in the Diagnostics section. select the Information Overlays drop-down arrow. In the Blocks section of the dialog, select Execution Oder. The Execution Oder viewer opens in a pane on the right-side of the Simulink Editor.

  2. Click a task in the task table.

    The selected row is highlighted in blue. All blocks in the task are highlighted on the block diagram. Execution order is displayed in red numbers for blocks in the task. Blocks in the other tasks are greyed out.

Execution Order API

Use the provided API to view tasks and execution order for blocks.

  1. Get the tasks in a model.

    <explain>

    >> sLists = get_param('mExample1', 'SortedLists')
    
    sLists = 
    
      2×1 struct array with fields:
    
        TaskIndex
        SampleTimes
        SortedBlocks
  2. Task index for the first task (Task 0 in the Execution Order viewer)

    <explain>

    >> sLists(1)
    ans = 
    
      struct with fields:
    
           TaskIndex: 0
         SampleTimes: [1×1 struct]
        SortedBlocks: [4×1 struct]
  3. Sample time details for Task 0.

    <explain>

    >> sLists(1).SampleTimes
    
    ans = 
    
      struct with fields:
    
           RateSpec: [1×1 struct]
         Annotation: 'D1'
        Description: 'Discrete 1'
    
    >> sLists(1).SampleTimes.RateSpec
    
    ans = 
    
      struct with fields:
    
          period: 1
          offset: 0
        rateType: 'ClassicPeriodicDiscrete'
    
    
  4. Blocks in Task 0.

    >> sLists(1).SortedBlocks.BlockType
    ans =
        'RateTransition'
    
    ans =
        'Abs'
    
    
    ans =
        'Scope'
    
    ans =
        'RateTransition'
    
  5. Details of the first block in Task 0.

    >> sLists(1).SortedBlocks(1)
    
    ans = 
    
      struct with fields:
    
         BlockHandle: 109.0001
          BlockPath: 'mExample1/D'
          BlockType: 'RateTransition'
         InputPorts: []
        OutputPorts: 1
  6. Get execution (sorted) order for a block.

    >> blockOrder = get_param('mExample1/D','SortedOrder')
    
    blockOrder = 
    
      struct with fields:
    
          TaskIndex: 0
        SystemIndex: 0
         BlockIndex: 1

Update Advisor Check for Data Store Memory Change

Using task-based sorting instead of block sorting can change the relative execution order involving Data Store Memory blocks. A Model Advisor check detects the changes and provides an option to update your model with the original execution order.

  1. Open the Upgrade Advisor. On the Modeling tab and in the Evaluate and Manage section, click Model Advisor. From the drop-down dialog, select Update Advisor.

  2. Select the check box for Check relative execution orders for Data Store Read and Data Store Write blocks.

  3. Click the Run This Check button.

  4. Review any changes in the Result table. If you want to keep the original execution order, click the Modify button.

Model Patterns with Task-Based Sorting

This section shows block execution order using task-based sorting for common model patterns.

Bus Expansion

Connecting a bus to the input of a Delay block creates multiple hidden blocks each with their own block execution order.

Algebraic Loop

Blocks within an algebraic loop are moved into a hidden non-virtual subsystem. The execution order of the hidden subsystem is determined within the context of the other model blocks, then the execution order of blocks within the hidden subsystem are determined.

Virtual Subsystems

For virtual subsystems, block execution order within the subsystem is listed in curly brackets {}.

Function-Call Subsystem Blocks

For Function-Call Subsystem blocks, the function-call Inport block, Subsystem block, and Outport block execute together. Since the execution order relative to other block in the model cannot be determined before simulation, the blocks display a function-call order using overlays such as F0 and F1.

You can view the execution order, including hidden blocks, with the following commands. The Inport block is associated with a hidden Function-Call Generator block, and the Function-Call Subsystem block is listed with an execution order of 2.

>> set_param('export_function_model','DisplaySortedLists','on')

>> get_param('export_function_model', 'SortedLists')

---- Sorted list for 'export_function_model' [6 nonvirtual block(s), directFeed=1]
     Total number of tasks = 2
- Sorted list of task index [1], 3 nonvirtual block(s)
  (1)0:1   'export_function_model/RootFcnCall_InsertedFor_function_call_1_at_outport_1' (RootInportFunctionCallGenerator)
          Input ports:  [0]
          Output ports: [0]
  (1)0:2   'export_function_model/Function-Call Subsystem 1' (SubSystem)
          Input ports:  [0]
          Output ports: [0]
  (1)0:3   'export_function_model/output_1' (Outport)
          Input ports:  [0]
          Output ports: []