Documentation Center

  • Trials
  • Product Updates

Build and Download to a Multicore Target

Generating Code

To generate code, in the Simulink® editor window, select Code > C/C++ Code > Build Model. The code generation process generates:

  • C code for parts of the model that are mapped to tasks and triggers in the Concurrent Execution dialog box. For more information, see Code Generation and Code Generation.

  • HDL code for parts of the model that are mapped to hardware nodes in the Concurrent Execution dialog box. For more information, see HDL Code Generation from Simulink.

  • Code to handle data transfer between the concurrent tasks and triggers and to interface with the hardware and software components.

The generated C code contains one function for each task or trigger defined in the system. The task and trigger determines the name of the function as follows:

void <TriggerName>_TaskName(void);

The content for each such function consists of target independent C code except for:

  • Code corresponding to blocks that implement target specific functionality

  • Customizations, including those derived from Custom Storage Classes or Code Replacement Libraries

  • Code that is generated to handle how data is transferred between tasks. In particular, Simulink Coder™ uses target specific implementations of mutual exclusion primitives and data synchronization semaphores to implement the data transfer as described in the following table of pseudocode.

Data TransferInitializationReaderWriter

Data Integrity Only

BufferIndex = 0;
Initialize Buffer[1] with IC
Begin mutual exclusion
 Tmp = 1 - BufferIndex;
End mutual exclusiton
 Read Buffer[ Tmp ];
Write Buffer[ BufferIndex ];
Begin mutual exclusion
BufferIndex = 1 - BufferIndex;
End mutual exclusion

Ensure Determinism (Maximum Delay)

WriterIndex = 0;
ReaderIndex = 1;
Initialize Buffer[1] with IC
Read Buffer[ ReaderIndex ];
ReaderIndex = 1 - ReaderIndex;
Write Buffer[ WriterIndex ]  
 WriterIndex = 1 - WriterIndex;

Ensure Determinism (Minimum Delay)

NA

Wait dataReady;
Read data;
Post readDone;
Wait readDone;
Write data;
Post dataReady;

Data Integrity Only

C-HDL interface

The Simulink Coder and HDL Coder™ products both take advantage of target specific communication implementations and devices to handle the data transfer between hardware and software components.

The generated HDL code contains one HDL project for each hardware node.

Customize the Generated C Code

The generated code is suitable for many different applications and development environments. To meet your needs, you can customize the generated C code as described in Target Development. In addition to those customization capabilities, for multicore and heterogeneous targets you can further customize the generated code as follows:

  • You can register your preferred implementation of mutual exclusion and data synchronization primitives using the code replacement library.

  • You can define a custom target architecture file that allows you to specify target specific properties for tasks and triggers in the Concurrent Execution dialog box. For more information, see Define a Custom Architecture File.

Define a Custom Architecture File

A custom architecture file is an XML file that allows you to define custom target properties for tasks and triggers. For example, you may want to define custom properties to represent the properties of threading APIs. Threading APIs are necessary to take advantage of concurrency on your target processor. The following is an example custom architecture file:

<architecture brief="Multicore with custom threading API"
              format="1.1"  revision="1.1"
              uuid="MulticoreCustomAPI"  name="MulticoreCustomAPI">
<configurationSet> 
     <parameter name="SystemTargetFile" value="ert.tlc"/> 
     <parameter name="SystemTargetFile" value="grt.tlc"/> 
</configurationSet>          
<node name="MulticoreProcessor" type="SoftwareNode" uuid="MulticoreProcessor"/>
<template name="CustomTask" type="Task" uuid="CustomTask">
     <property name="affinity" prompt="Affinity:" value="1" evaluate="true"/>
     <property name="schedulingPolicy" prompt="Scheduling policy:" value="Rate-monotonic">
           <allowedValue>Rate-monotonic</allowedValue>
           <allowedValue>Round-robin</allowedValue>
        </property>
   </template>
</architecture>

An architecture file must contain:

  • The architecture element that defines basic information Simulink uses to identify the architecture.

  • A configurationSet element that lists the system target files for which this architecture is valid.

  • One node element that Simulink uses to identify the multicore processing element.

      Note:   The architecture must contain exactly one node element that identifies a multicore processing element. You cannot create multiple nodes identifying multiple processing elements or an architecture with no multicore processing element.

  • One or more template elements that lists custom properties for tasks and triggers.

    • The type attribute can be Task, PeriodicTrigger, or AperiodicTrigger.

    • Each property is editable and has the default value specified in the value attribute.

    • Each property can be a text box, check box, or combo box. A check box is one where you can set the value attribute to on or off. A combo box is one where you can optionally list allowedValue elements as part of the property.

    • Each text box property can also optionally define an evaluate attribute. This lets you place MATLAB® variable names as the value of the property.

    Assuming that you have saved the custom target architecture file in C:\custom_arch.xml, register this file with Simulink using the Simulink.architecture.register function.

For example,

  1. Save the contents of the listed XML file in custom_arch.xml.

  2. In the MATLAB Command Window, type:

    Simulink.architecture.register('custom_arch.xml') 
  3. In the MATLAB Command Window, type:

    sldemo_concurrent_execution
  4. In the Simulink editor, open the Configuration Parameters > Solver pane and click Configure Tasks.

    The Concurrent Execution dialog box displays.

  5. In the Concurrent Execution pane, click Select... for Target Architecture.

    The Target architecture window displays.

  6. Click MulticoreCustomAPI and click OK.

Your Concurrent Execution dialog box updates to contain Code Generation properties for the tasks as shown. These are the properties defined in the XML file.

Native Threads Example

Simulink Coder and Embedded Coder® targets provide an example target to generate code for Windows®, Linux® and Mac OS operating systems.

For an Embedded Coder target, in the Configuration Parameters dialog box:

  • Select the Code Generation > Templates > Generate an example main program check box.

  • From the Code Generation > Templates > Target Operating System list, select NativeThreadsExample.

The native threads example illustrates how Simulink Coder and Embedded Coder leverage target specific threading APIs and data management primitives, as shown in Threading APIs used by Native Threads Example.

Threading APIs used by Native Threads Example

Aspect of Concurrent ExecutionLinux ImplementationWindows ImplementationMac OS Implementation

Periodic triggering event

POSIX timer

Windows timer

Not applicable

Aperiodic triggering event

POSIX real-time signal

Windows event

POSIX non-real-time signal

Aperiodic trigger

For blocks mapped to an aperiodic task: thread waiting for a signal

For blocks mapped to an aperiodic trigger: signal action

Thread waiting for an event

For blocks mapped to an aperiodic task: thread waiting for a signal

For blocks mapped to an aperiodic trigger: signal action

Threads

POSIX®

Windows

POSIX

Threads priority

Assigned based on sample time: fastest task has highest priority

Priority class inherited from the parent process.

Assigned based on sample time: fastest task has highest priority for the first three fastest tasks. The rest of the tasks share the lowest priority.

Assigned based on sample time: fastest task has highest priority

Example of overrun detection

Yes

Yes

No

The data transfer between concurrently executing tasks behave as described in Data Transfer Options. The coders use the following APIs on supported targets for this behavior:

Data Protection and Synchronization APIs Used by Native Threads Example

APILinux ImplementationWindows ImplementationMac OS Implementation
Data protection API
  • pthread_mutex_init

  • pthread_mutex_destroy

  • pthread_mutex_lock

  • pthread_mutex_unlock

  • CreateMutex

  • CloseHandle

  • WaitForSingleObject

  • ReleaseMutex

  • pthread_mutex_init

  • pthread_mutex_destroy

  • pthread_mutex_lock

  • pthread_mutex_unlock

Synchronization API
  • sem_init

  • sem_destroy

  • sem_wait

  • sem_post

  • CreateSemaphore

  • CloseHandle

  • WaitForSingleObject

  • ReleaseSemaphore

  • sem_open

  • sem_unlink

  • sem_wait

  • sem_post

Profile and Evaluate

Profile the execution of your code on the multicore target using the Profile Report pane of the Concurrent Execution dialog box. You can profile using Simulink Coder (GRT) and Embedded Coder (ERT) targets. Profiling helps you identify the areas in your model that are execution bottlenecks. You can analyze the execution time of each task and find the task that takes most of the execution time. For example, you can compare the average execution times of the tasks. If a task is computation intensive, or does not satisfy real-time requirements and overruns, you can break it into tasks that are less computation intensive and that can run concurrently.

When you generate a profile report, the software:

  1. Builds the model.

  2. Generates code for the model.

  3. Adds tooling to the generated code to collect data.

  4. Executes the generated code on the target and collects data.

  5. Collates the data, generates an HTML file (model_name_ProfileReport.html) in the current folder, and displays that HTML file in the Profile Report pane of the Concurrent Execution dialog box.

      Note:   If an HTML profile report exists for the model, the Profile Report pane displays that file. To generate a new profile report, click .

SectionDescription

Summary

Summarizes model execution statistics, such as total execution time and profile report creation time. It also lists the total number of cores on the host machine.

Task Execution Time

Displays the execution time, in microseconds, for each task in a pie chart color coded by task.

Visible for Windows, Linux, and Mac OS platforms.

Task Affinitization to Processor Cores

Platform-dependent. For each time step and task, displays the processor core number the task started executing on at that time step, color coded by processor.

If there is no task scheduled for a particular time step, NR is displayed.

Visible for Windows and Linux platforms.

After you analyze the profile report, consider explicitly changing the mapping of Model blocks to efficiently use the concurrency available on your multicore system (see Map Blocks to Tasks, Triggers, and Nodes.

Some products, such as Simulink Real-Time™ and Embedded Coder, have tools you can use to profile execution for particular targets:

ProductFor more information, see...
Simulink Real-TimeExecution Profiling for Target Applications
Embedded CoderPerform Execution Time Profiling for IDE and Toolchain Targets

Generate Profile Report

This topic assumes a previously configured model ready to be profiled for concurrent execution. Otherwise, see Configure Your Model.

  1. In the Concurrent Execution dialog box, click the Profile report node.

    The profile tool looks for a file named model_name_ProfileReport.html. If such a file does not exist for the current model, the Profile Report pane displays:

      Note:   If an HTML profile report exists for the model, the Profile Report pane displays that file. To generate a new profile report, click .

  2. Enter the number of time steps for which you want the profiler to collect data for the model execution.

  3. Click the Generate task execution profile report button.

    This action builds the model, generates the code, adds data collection tooling to the code, and then executes the code on the target, which also generates an HTML profile report. This process can take several minutes. When the process is complete, the contents of the profile report appear in the Profile Report pane. For example:

  4. Analyze the profile report, create and reassign new tasks as needed, and regenerate the profile report.

Generate Profile Report at Command Line

Alternatively, you can generate a profile report for a model configured for concurrent execution at the command line. Use the Simulink.architecture.profile function.

For example, to create a profile report for the model sldemo_concurrent_execution:

Simulink.architecture.profile('sldemo_concurrent_execution');

To create a profile report with a specific number of samples (100) for the model sldemo_concurrent_execution:

Simulink.architecture.profile('sldemo_concurrent_execution',120);

The function creates a profile report named sldemo_concurrent_execution_ProfileReport.html in your current folder.

Was this topic helpful?