Main Content

Optimize Performance of Memory Access by Using Data Alignment

This example shows how to specify the data alignment requirements for data objects such as Simulink.Parameter, Simulink.Signal, and Simulink.Bus objects. To instruct the compiler to align data objects on specific boundaries in memory, configure your data for data alignment. Data alignment can improve the performance of memory access for some target processors and is sometimes required for the code to execute.

For information about specifying data alignment for a code replacement entry, see Data Alignment for Code Replacement.

For information about specifying data alignment for MATLAB® code, see coder.dataAlignment.

Specify Data Alignment Requirements for Data Object

To specify the alignment boundary of a data object, set the Alignment property by using one of these methods:

  • Type Editor

  • Dialog box editor for the data object

  • Programmatic interface for the object

Data objects that support data alignment specification include:

Once you specify the data alignment boundaries for your data objects, provide the data alignment specification for the compiler by using a code replacement library. You do not need to specify code replacements in the library.

Provide Data Alignment Specification for Compilers

To support data alignment in generated code, describe the data alignment capabilities and syntax for your compilers in the code replacement library registration. Provide one or more alignment specifications for each compiler in a library registry entry.

  • If you are defining a code replacement library registration entry in a rtwTargetInfo.m customization file, add one or more AlignmentSpecification objects to an RTW.DataAlignment object. Attach the RTW.DataAlignment object to the TargetCharacteristics object of the registry entry.

    An example of a data alignment specification for the GCC compiler follows.

    da = RTW.DataAlignment;
    
    as = RTW.AlignmentSpecification;
    as.AlignmentType = {'DATA_ALIGNMENT_LOCAL_VAR', ...
                        'DATA_ALIGNMENT_STRUCT_FIELD', ...
                        'DATA_ALIGNMENT_GLOBAL_VAR'};
    as.AlignmentSyntaxTemplate = '__attribute__((aligned(%n)))';
    as.AlignmentPosition = 'DATA_ALIGNMENT_PREDIRECTIVE';
    as.SupportedLanguages = {'c', 'c++'};
    da.addAlignmentSpecification(as);
    
    tc = RTW.TargetCharacteristics;
    tc.DataAlignment = da;

    The RTW.DataAlignment object also has the property DefaultMallocAlignment, which specifies the default alignment boundary, in bytes, that the compiler uses for dynamically allocated memory. If the code generator uses dynamic memory allocation for a data object involved in a code replacement, this value determines if the memory satisfies the alignment requirement of the replacement. If not, the code generator does not use the replacement. The default value for DefaultMallocAlignment is -1, indicating that the default alignment boundary used for dynamically allocated memory is unknown. In this case, the code generator uses the natural alignment of the data type to determine whether to allow a replacement.

    Additionally, you can specify the alignment boundary for complex types by using the addComplexTypeAlignment function.

  • If you are generating a customization file function using the Code Replacement Tool, fill out the following fields for each compiler.

    Generate registration file dialog showing the Generate data alignment specification option selected. The Alignment Specification 1 section shows the options alignment type, alignment position, alignment syntax, and supported languages.

    Click the plus (+) symbol to add additional compiler specifications.

    Here is the specification for the GCC compiler in the Generate registration file dialog box of the Code Replacement Tool.

    Data alignment specifications in the Generate registration file dialog box.

For each data alignment specification, provide the following information.

AlignmentSpecification Property

Dialog Box Parameter

Description

AlignmentType

Alignment type

Cell array of predefined enumerated strings specifying the types of alignment this specification supports.

  • DATA_ALIGNMENT_LOCAL_VAR — Local variables

  • DATA_ALIGNMENT_GLOBAL_VAR — Global variables

  • DATA_ALIGNMENT_STRUCT_FIELD — Individual structure fields

  • DATA_ALIGNMENT_WHOLE_STRUCT — Whole structure, with padding (individual structure field alignment, if specified, is favored by the code generator and takes precedence over whole structure alignment)

Each alignment specification must specify at least DATA_ALIGNMENT_GLOBAL_VAR and DATA_ALIGNMENT_STRUCT_FIELD.

AlignmentPosition

Alignment position

Predefined enumerated string specifying the position in which you must place the compiler alignment directive for the alignment type DATA_ALIGNMENT_WHOLE_STRUCT:

  • DATA_ALIGNMENT_PREDIRECTIVE — The alignment directive is emitted before struct st_tag{…} as part of the type definition statement (for example, MSVC).

  • DATA_ALIGNMENT_POSTDIRECTIVE — The alignment directive is emitted after struct st_tag{…} as part of the type definition statement (for example, gcc).

  • DATA_ALIGNMENT_PRECEDING_STATEMENT — The alignment directive is emitted as a standalone statement immediately preceding the definition of the structure type. A semicolon (;) must terminate the registered alignment syntax.

  • DATA_ALIGNMENT_FOLLOWING_STATEMENT — The alignment directive is emitted as a standalone statement immediately following the definition of the structure type. A semicolon (;) must terminate the registered alignment syntax.

For alignment types other than DATA_ALIGNMENT_WHOLE_STRUCT, code generation uses the alignment position DATA_ALIGNMENT_PREDIRECTIVE.

AlignmentSyntaxTemplate

Alignment syntax

Specify the alignment directive string that the compiler supports. The string is registered as a syntax template that has placeholders in it. These placeholders are supported:

  • %n — Replaced by the alignment boundary for the replacement function argument.

  • %s — Replaced by the aligned symbol, usually the identifier of a variable.

For example, for the gcc compiler, you can specify __attribute__((aligned(%n))), or for the MSVC compiler, __declspec(align(%n)).

SupportedLanguages

Supported languages

Cell array specifying the languages to which this alignment specification applies, among c and c++. Sometimes, alignment syntax and position differ between languages for a compiler.

Basic Example of Data Object Alignment

This example shows how to specify the data alignment for two Simulink.Bus objects.

  1. Open the example model PreserveBusDims. This model uses two Simulink.Bus objects stored in the base workspace.

    openExample("PreserveBusDims")

    The model contains two bus ports, which resolve to Simulink.Bus objects in the base workspace.

  2. Set the data alignment for the data objects. For this example, set the alignment for the bus objects ImperialSpecs and MetricSpecs to 64.

    ImperialSpecs.Alignment = 64;
    MetricSpecs.Alignment = 64;

  3. Create and save the following code replacement table definition file, crl_table_align.m. You use this table because data alignment compiler specification requires that you register a code replacement library. The table does not contain code replacement entries, it only specifies the compiler information needed for data alignment.

    function hLib = crl_table_align
    
    hLib = RTW.TflTable;
  4. Create and save the following registration file, rtwTargetInfo.m. If you want to compile the code generated in this example, first modify the AlignmentSyntaxTemplate property for the compiler that you use. For example, for the MSVC compiler, replace the gcc template specification __attribute__((aligned(%n))) with __declspec(align(%n)).

    function rtwTargetInfo(cm)
    % rtwTargetInfo function to register a code replacement library (CRL)
    % for use with code generation
    
      % Register the CRL defined in local function locCrlRegFcn
      cm.registerTargetInfo(@locCrlRegFcn);
    
    end % End of RTWTARGETINFO
    
    % Local function to define a CRL containing crl_table_align
    function thisCrl = locCrlRegFcn
    
      % Create an alignment specification object, assume gcc
      as = RTW.AlignmentSpecification;
      as.AlignmentType = {'DATA_ALIGNMENT_LOCAL_VAR', ...
                          'DATA_ALIGNMENT_GLOBAL_VAR', ...
                          'DATA_ALIGNMENT_STRUCT_FIELD'};
      as.AlignmentSyntaxTemplate = '__attribute__((aligned(%n)))';
      as.SupportedLanguages={'c', 'c++'};
    
      % Add the alignment specification object
      da = RTW.DataAlignment;
      da.addAlignmentSpecification(as);
    
      % Add the data alignment object to target characteristics
      tc = RTW.TargetCharacteristics;
      tc.DataAlignment = da;
    
      % Instantiate a CRL registry entry
      thisCrl = RTW.TflRegistry;
    
      % Define the CRL properties
      thisCrl.Name = 'Data Alignment Example';
      thisCrl.Description = 'Example of replacement with data alignment';
      thisCrl.TableList = {'crl_table_align'};
        thisCrl.TargetCharacteristics = tc;
    
    end % End of LOCCRLREGFCN
  5. To register your library with the code generator, enter this command.

    RTW.TargetRegistry.getInstance('reset');
  6. Configure the model to use your code replacement library.

    set_param("PreserveBusDims","CodeReplacementLibrary","Data Alignment Example");

  7. Generate code for the model.

    slbuild("PreserveBusDims");

  8. Check that the generated code aligns the data by using the alignment syntax that you specified. For this example, PreserveBusDims.h contains this code.

    
    #ifndef DEFINED_TYPEDEF_FOR_MetricSpecs_
    #define DEFINED_TYPEDEF_FOR_MetricSpecs_
    
    typedef struct {
      __attribute__((aligned(64))) real_T DimensionsInCms[30];
      __attribute__((aligned(64))) real_T WeightInKilograms[10];
    } MetricSpecs;
    
    #endif
    
    #ifndef DEFINED_TYPEDEF_FOR_ImperialSpecs_
    #define DEFINED_TYPEDEF_FOR_ImperialSpecs_
    
    typedef struct {
      __attribute__((aligned(64))) real_T DimensionsInInches[30];
      __attribute__((aligned(64))) real_T WeightInPounds[10];
    } ImperialSpecs;
    
    #endif

Data Alignment Limitations

When you try to perform data alignment in a case that is not supported:

  • If you specify the data alignment by using only a data object, the code generator produces an error.

  • If you specify the data alignment by using a code replacement entry, replacement does not occur. The code generator also produces an error for some cases.

Data alignment is not supported for:

  • Software-in-the-loop (SIL)

  • Processor-in-the-loop (PIL)

  • Model reference parameters

  • Exported functions in Stateflow® charts

  • Functions that are generated with C function prototype control or C++ class I/O arguments step method and that use root-level I/O variables

  • Functions that are generated with the AUTOSAR system target file and that use root-level I/O or AUTOSAR inter-runnable access functions

If the following conditions exist, the code generator includes data alignment directives for root-level I/O variables in the ert_main.c or ert_main.cpp file it produces. In this case, if you discard the generated example main program, align used root-level I/O variables correctly. If you choose not to generate an example main program in this case, data alignment is not supported.

  • Compiler supports global variable alignment

  • Generate an example main program (select Configuration Parameters > Generate an example main program)

  • Generate a reusable function interface for the model (set Configuration Parameters > Code Generation > Interface > Code interface packaging to Reusable function)

  • Function uses root-level I/O variables that are passed in as individual arguments (set Configuration Parameters > Code Generation > Interface > Pass root-level I/O asto Individual arguments)

  • Function uses a root-level I/O variable

  • Function imposes alignment requirements

If a replacement imposes alignment requirements on the shared utility interface arguments, the code generator does not honor data alignment. Under these conditions, replacement does not occur. Replacement is allowed if the registered data alignment type specification supports alignment of local variables, and the replacement involves only local variables.

For Simulink.Bus objects:

  • If user registered alignment specifications do not support structure field alignment, aligning Simulink.Bus objects is not supported unless the Simulink.Bus object is imported.

  • When you align a Simulink.Bus data object, the elements in the bus object are aligned on the same boundary. The boundary is the lowest common multiple of the alignment requirements for each individual bus element.

When you specify alignment for functions that occur in a model reference hierarchy, and multiple models in the hierarchy operate on the same function data, the bottommost model dictates alignment for the rest of the hierarchy. If the alignment requirement for a function in a model higher in the hierarchy cannot be honored due to the alignment set by a model lower in the hierarchy, data alignment is not supported. To work around this issue, if the shared data is represented by a bus or signal object, manually set the alignment property on the shared data by setting the alignment property of the Simulink.Bus or Simulink.Signal object.

Storage Class Limitations

Data that is associated with storage classes supports alignment only under certain conditions. This table shows the built-in storage classes that support data alignment and the required conditions.

Storage ClassConditions
DefaultNone
ExportedGlobalNone
ImportedExternSpecify the data alignment by using a data object. Specification by using a code replacement entry is not supported.
ImportedExternPointerSpecify the data alignment by using a data object. Specification by using a code replacement entry is not supported.
VolatileNone
ConstNone
ConstVolatileNone
ExportToFileNone
ImportedFromFileSpecify the data alignment by using a data object. Specification by using a code replacement entry is not supported.
LocalizableNot supported for root input ports
GetSetNot supported
MultiInstanceNone
FileScopeNot supported when used from an Embedded Coder Dictionary
StructNone
ReusableNone
BitfieldNot supported
DefineNot supported
ImportedDefineSpecify the data alignment by using a data object. Specification by using a code replacement entry is not supported.
CompilerFlagSpecify the data alignment by using a data object. Specification by using a code replacement entry is not supported.

For storage classes that you create by using the Embedded Coder Dictionary or the Custom Storage Class Designer, data alignment is not supported if the storage class has:

  • Data Access set to Pointer or Function

  • Data Scope set to Exported and:

    • Data Initialization set to Macro

    • Bit-Pack Boolean selected (available in Custom Storage Class Designer only)

    • Type set to Other (available in Custom Storage Class Designer only)

Related Topics