Code replacement libraries can align data objects passed into a replacement function to a specified boundary.
You can take advantage of function implementations that require aligned data to optimize application performance. To configure data alignment for a function implementation:
Specify the data alignment requirements in a code replacement entry. Specify alignment separately for each implementation function argument or collectively for all function arguments. See Specify Data Alignment Requirements for Function Arguments.
Specify the data alignment capabilities and syntax
for one or more compilers. Include the alignment specifications in
a library registration entry in the rtwTargetInfo.m
file.
See Provide Data Alignment Specifications for Compilers.
Register the library containing the table entry and alignment specification object.
Configure the code generator to use the code replacement library and generate code. Observe the results.
For examples, see Basic Example of Code Replacement Data Alignment and the “Data Alignment for Function Implementations” section of the Optimize Generated Code By Developing and Using Code Replacement Libraries - Simulink® example page.
To specify the data alignment requirement for an argument in a code replacement entry:
If you are defining a replacement function in a code
replacement table registration file, create an argument descriptor
object (RTW.ArgumentDescriptor
). Use its AlignmentBoundary
property
to specify the required alignment boundary and assign the object to
the argument Descriptor
property.
If you are defining a replacement function using the Code Replacement Tool, on the Mapping Information tab, in the Argument properties section for the replacement function, enter a value for the Alignment value parameter.
The AlignmentBoundary
property (or Alignment
value parameter) specifies the alignment boundary for data
passed to a function argument, in number of bytes. The AlignmentBoundary
property
is valid only for addressable objects, including matrix and pointer
arguments. It is not applicable for value arguments. Valid values
are:
-1
(default) — If the data
is a Simulink.Bus
, Simulink.Signal
,
or Simulink.Parameter
object, specifies that the
code generator determines an optimal alignment based on usage. Otherwise,
specifies that there is not an alignment requirement for this argument.
Positive integer that is a power of 2, not exceeding 128 — Specifies number of bytes in the boundary. The starting memory address for the data allocated for the function argument is a multiple of the specified value. If you specify an alignment boundary that is less than the natural alignment of the argument data type, the alignment directive is emitted in the generated code. However, the target compiler ignores the directive.
The following code specifies the AlignmentBoundary
for
an argument as 16 bytes.
hLib = RTW.TflTable; entry = RTW.TflCOperationEntry; arg = getTflArgFromString(hLib, 'u1','single*'); desc = RTW.ArgumentDescriptor; desc.AlignmentBoundary = 16; arg.Descriptor = desc; entry.Implementation.addArgument(arg);
The equivalent alignment boundary specification in the Code Replacement Tool dialog box is in this figure.
Note
If your model imports Simulink.Bus
, Simulink.Parameter
,
or Simulink.Signal
objects, specify an alignment
boundary in the object properties, using the Alignment property.
For more information, see Simulink.Bus
, Simulink.Parameter
,
and Simulink.Signal
.
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.
To describe the data alignment capabilities and syntax for a compiler:
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.
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.
Click the plus (+) symbol to add additional compiler specifications.
For each data alignment specification, provide the following information.
|
Dialog Box Parameter |
Description |
---|---|---|
|
Alignment type | Cell array of predefined enumerated strings, specifying which types of alignment this specification supports.
Each alignment specification
must specify at least
|
|
Alignment position | Predefined enumerated string
specifying the position in which you must place
the compiler alignment directive for alignment
type
For alignment types other
than
|
|
Alignment syntax | Specifies 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:
For example, for the gcc
compiler, you can specify
|
|
Supported languages |
Cell array specifying the languages to which
this alignment specification applies, among
|
Here is a data alignment specification for the GCC compiler:
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;
Here is the corresponding specification in the Generate customization dialog box of the Code Replacement Tool.
A simple example of the complete workflow for data alignment specified for code replacement is:
Create and save the following code replacement table
definition file, crl_table_mmul_4x4_single_align.m
.
This table defines a replacement entry for the * (multiplication)
operator, the single
data type, and input dimensions [4,4]
.
The entry also specifies a data alignment boundary of 16 bytes for
each replacement function argument. The entry expresses the requirement
that the starting memory address for the data allocated for the function
arguments during code generation is a multiple of 16.
function hLib = crl_table_mmul_4x4_single_align %CRL_TABLE_MMUL_4x4_SINGLE_ALIGN - Describe matrix operator entry with data alignment hLib = RTW.TflTable; entry = RTW.TflCOperationEntry; setTflCOperationEntryParameters(entry, ... 'Key', 'RTW_OP_MUL', ... 'Priority', 90, ... 'ImplementationName', 'matrix_mul_4x4_s'); % conceptual arguments createAndAddConceptualArg(entry, 'RTW.TflArgMatrix',... 'Name', 'y1', ... 'IOType', 'RTW_IO_OUTPUT', ... 'BaseType', 'single', ... 'DimRange', [4 4]); createAndAddConceptualArg(entry, 'RTW.TflArgMatrix',... 'Name', 'u1', ... 'BaseType', 'single', ... 'DimRange', [4 4]); createAndAddConceptualArg(entry, 'RTW.TflArgMatrix',... 'Name', 'u2', ... 'BaseType', 'single', ... 'DimRange', [4 4]); % implementation arguments arg = getTflArgFromString(hLib, 'y2', 'void'); arg.IOType = 'RTW_IO_OUTPUT'; entry.Implementation.setReturn(arg); arg = getTflArgFromString(hLib, 'y1','single*'); arg.IOType = 'RTW_IO_OUTPUT'; desc = RTW.ArgumentDescriptor; desc.AlignmentBoundary = 16; arg.Descriptor = desc; entry.Implementation.addArgument(arg); arg = getTflArgFromString(hLib, 'u1','single*'); desc = RTW.ArgumentDescriptor; desc.AlignmentBoundary = 16; arg.Descriptor = desc; entry.Implementation.addArgument(arg); arg = getTflArgFromString(hLib, 'u2','single*'); desc = RTW.ArgumentDescriptor; desc.AlignmentBoundary = 16; arg.Descriptor = desc; entry.Implementation.addArgument(arg); hLib.addEntry(entry);
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_mmul_4x4_single_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_mmul_4x4_single_align'}; thisCrl.TargetCharacteristics = tc; end % End of LOCCRLREGFCN
To register your library with code generator without having to restart MATLAB®, enter this command:
RTW.TargetRegistry.getInstance('reset');
Configure the code generator to use your code replacement library.
Generate code and a code generation report.
Review the code replacements. For example, check whether
a multiplication operation is replaced with a matrix_mul_4x4_s
function
call. In mmalign.h
, check whether the gcc alignment
directive __attribute__((aligned(16)))
is generated
to align the function variables.