Выравнивание данных для замены кода

Заменяющие библиотеки кода могут выровняться, объекты данных передали в заменяющую функцию заданному контуру.

Заменяющее выравнивание данных кода

Можно использовать в своих интересах реализации функции, которые требуют, чтобы выровненные данные оптимизировали производительность приложения при использовании MATLAB® Coder™. Сконфигурировать выравнивание данных для реализации функции:

  1. Задайте требования выравнивания данных в заменяющей записи кода. Задайте выравнивание отдельно для каждого аргумента функции реализации или коллективно для всех аргументов функции. Смотрите Задают Требования Выравнивания Данных для Аргументов функции.

  2. Задайте возможности выравнивания данных и синтаксис для одного или нескольких компиляторов. Включайте спецификации выравнивания в регистрационную запись библиотеки в файле rtwTargetInfo.m. Смотрите Обеспечивают Спецификации Выравнивания Данных для Компиляторов.

  3. Укажите библиотеку, содержащую запись таблицы и объект спецификации выравнивания.

  4. Сконфигурируйте генератор кода, чтобы пользоваться заменяющей библиотекой кода и сгенерировать код. Наблюдайте результаты.

Для примеров смотрите Основной Пример Заменяющего Выравнивания Данных Кода и раздел “Data Alignment for Function Implementations” Оптимизировать Сгенерированного кода Путем Разработки и пользования Заменяющими Библиотеками Кода - страница Simulink® в качестве примера.

Примечание

Если замена, которая требует использования выравнивания импортированные данные (например, ввод-вывод функции точки входа или экспортируемой функции), задает выравнивание данных с операторами coder.dataAlignment в коде MATLAB. Задайте выравнивание отдельно для каждого экземпляра импортированных данных. Смотрите Задают Выравнивание Данных в коде MATLAB для Импортированных Данных.

Задайте требования выравнивания данных для аргументов функции

Задавать требование выравнивания данных для аргумента в заменяющей записи кода:

  • Если вы задаете заменяющую функцию в заменяющем табличном регистрационном файле кода, создаете объект дескриптора аргумента (RTW.ArgumentDescriptor). Используйте его свойство AlignmentBoundary задать необходимый контур выравнивания и присвоить объект свойству аргумента Descriptor.

  • Если вы задаете заменяющую функцию, использование Code Replacement Tool, на вкладке Mapping Information, в разделе Argument properties для заменяющей функции, вводит значение для параметра Alignment value.

Свойство AlignmentBoundary (или параметр Alignment value) указывает, что контур выравнивания для данных передал аргументу функции в количестве байтов. Свойство AlignmentBoundary допустимо только для адресуемых объектов, включая аргументы указателя и матрицу. Это не применимо для аргументов значения. Допустимые значения:

  • -1 (значение по умолчанию) — Если данными является Simulink.Bus, Simulink.Signal или объект Simulink.Parameter, указывает, что генератор кода определяет оптимальное выравнивание на основе использования. В противном случае, указывает, что нет требования выравнивания для этого аргумента.

  • Положительное целое число, которое является степенью 2, не превышая 128 — Задает количество байтов в контуре. Стартовый адрес памяти для данных, выделенных для аргумента функции, является кратным заданному значению. Если вы задаете контур выравнивания, который является меньше, чем естественное выравнивание типа данных аргумента, директива выравнивания испускается в сгенерированном коде. Однако целевой компилятор игнорирует директиву.

Следующий код задает AlignmentBoundary для аргумента как 16 байтов.

hLib = RTW.TflTable;
entry = RTW.TflCOperationEntry;
arg = getTflArgFromString(hLib, 'u1','single*');
desc = RTW.ArgumentDescriptor;
desc.AlignmentBoundary = 16;
arg.Descriptor = desc;
entry.Implementation.addArgument(arg);

Эквивалентная спецификация контура выравнивания в диалоговом окне Code Replacement Tool находится в этой фигуре.

Примечание

Если ваша модель импортирует Simulink.Bus, Simulink.Parameter или объекты Simulink.Signal, задайте контур выравнивания в свойствах объектов, с помощью свойства Alignment. Для получения дополнительной информации смотрите Simulink.Bus, Simulink.Parameter и Simulink.Signal.

Обеспечьте спецификации выравнивания данных для компиляторов

Чтобы поддержать выравнивание данных в сгенерированном коде, опишите возможности выравнивания данных и синтаксис для ваших компиляторов в заменяющей регистрации библиотеки кода. Обеспечьте одну или несколько спецификаций выравнивания для каждого компилятора в ключе реестра библиотеки.

Описать возможности выравнивания данных и синтаксис для компилятора:

  • Если вы задаете заменяющую регистрационную запись библиотеки кода в файле настройки rtwTargetInfo.m, добавьте один или несколько объектов AlignmentSpecification в объект RTW.DataAlignment. Присоедините объект RTW.DataAlignment к объекту TargetCharacteristics ключа реестра.

    Объект RTW.DataAlignment также имеет свойство DefaultMallocAlignment, которое задает контур выравнивания по умолчанию в байтах, что компилятор использует для динамически выделенной памяти. Если генератор кода использует динамическое выделение памяти для объекта данных, вовлеченного в замену кода, это значение определяет, удовлетворяет ли память требование выравнивания замены. В противном случае генератор кода не использует замену. Значением по умолчанию для DefaultMallocAlignment является -1, указывая, что контур выравнивания по умолчанию, используемый для динамически выделенной памяти, неизвестен. В этом случае генератор кода использует естественное выравнивание типа данных, чтобы определить, позволить ли замену.

    Кроме того, можно задать контур выравнивания для составных типов при помощи функции addComplexTypeAlignment.

  • Если вы генерируете функцию файла настройки использование Заменяющего Инструмента Кода, заполняете следующие поля для каждого компилятора.

    Щелкните плюс (+) символ, чтобы добавить дополнительные спецификации компилятора.

Для каждой спецификации выравнивания данных предоставьте следующую информацию.

Свойство AlignmentSpecificationПараметр диалогового окнаОписание
AlignmentTypeAlignment type

Массив ячеек предопределенных перечислимых строк, задавая, который типы выравнивания эта спецификация поддержки.

  • DATA_ALIGNMENT_LOCAL_VAR — Локальные переменные.

  • DATA_ALIGNMENT_GLOBAL_VAR — Глобальные переменные.

  • DATA_ALIGNMENT_STRUCT_FIELD — Отдельные поля структуры.

  • DATA_ALIGNMENT_WHOLE_STRUCT — Целая структура, с дополнением (отдельное полевое выравнивание структуры, если задано, одобрено и более приоритетно по сравнению с целым выравниванием структуры).

Каждая спецификация выравнивания должна задать, по крайней мере, DATA_ALIGNMENT_GLOBAL_VAR и DATA_ALIGNMENT_STRUCT_FIELD.

AlignmentPositionAlignment position

Предопределенная перечисленная строка, задающая положение, в которое необходимо поместить директиву выравнивания компилятора для выравнивания, вводит DATA_ALIGNMENT_WHOLE_STRUCT:

  • DATA_ALIGNMENT_PREDIRECTIVE — Директива выравнивания испускается перед struct st_tag{…}, как часть оператора определения типа (например, MSVC).

  • DATA_ALIGNMENT_POSTDIRECTIVE — Директива выравнивания испускается после struct st_tag{…}, как часть оператора определения типа (например, gcc).

  • DATA_ALIGNMENT_PRECEDING_STATEMENT — Директива выравнивания испускается как автономный оператор, сразу предшествующий определению типа структуры. Точка с запятой (;) должен отключить зарегистрированный синтаксис выравнивания.

  • DATA_ALIGNMENT_FOLLOWING_STATEMENT — Директива выравнивания испускается как автономный оператор сразу после определения типа структуры. Точка с запятой (;) должен отключить зарегистрированный синтаксис выравнивания.

Для типов выравнивания кроме DATA_ALIGNMENT_WHOLE_STRUCT генерация кода использует положение выравнивания DATA_ALIGNMENT_PREDIRECTIVE.

AlignmentSyntaxTemplateAlignment syntax

Задает направляющую строку выравнивания, которую поддерживает компилятор. Строка указана как шаблон синтаксиса, который имеет заполнителей в ней. Эти заполнители поддерживаются:

  • N Замененный контуром выравнивания для заменяющего аргумента функции.

  • S Замененный выровненным символом, обычно идентификатор переменной.

Например, для gcc компилятора, можно задать __attribute__((aligned(%n))), или для компилятора MSVC, __declspec(align(%n)).

SupportedLanguagesSupported languages

Массив ячеек, задающий языки, к которым эта спецификация выравнивания применяется среди c и c++. Иногда синтаксис выравнивания и положение отличаются между языками для компилятора.

Вот спецификация выравнивания данных для компилятора GCC:

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;

Вот соответствующая спецификация в диалоговом окне Generate customization Заменяющего Инструмента Кода.

Задайте выравнивание данных в коде MATLAB для импортированных данных

Если замены MATLAB Coder кода, которые требуют использования выравнивания данных импортированные данные, такие как точка входа или экспортировали функциональный ввод-вывод, задают выравнивание данных к внешнему коду с операторами coder.dataAlignment в коде MATLAB.

Если замены MATLAB Coder кода происходят, которые требуют выравнивания данных (использование импортированные данные), такое как точка входа или экспортируемая функция с вводом-выводом, задают заменяющее выравнивание данных кода с операторами coder.DataAlignment в коде MATLAB.

Задавать требования выравнивания данных для импортированных данных в коде MATLAB:

  • Для каждого экземпляра импортированных данных, которые требуют выравнивания данных, задайте выравнивание в функции с оператором coder.dataAlignment формы:

    coder.dataAlignment('varName', align_value)

  • varName является символьным массивом имени переменной, которое требует спецификации информации о выравнивании. align_value является целым числом, которое должно быть степенью 2, от 2 до 128. Этот номер задает power-2 контур выравнивания байта.

  • Функция, взятая в качестве примера, которая задает выравнивание данных:

    function y = testFunction(x1,x2)
    
    coder.dataAlignment('x1',16);	  % Specifies information
    coder.dataAlignment('x2',16);    % Specifies information
    coder.dataAlignment('y',16);     % Specifies information
    
    y = x1 + x2;
    
    end
    

Если testFunction является точкой входа или экспортировал функцию, импортированные данные x1, x2, и y не выравнивается автоматически генератором кода. Операторы coder.DataAlignment для этих переменных только предназначены как информация для генератора кода. Сайты вызова, выделяющие память для данных, должны гарантировать, что данные выравниваются, как задано.

Также можно задать заменяющее выравнивание данных кода для экспортированных данных, таких как переменная global или ExportedGlobal пользовательский класс памяти. Для получения дополнительной информации смотрите Встроенные Классы памяти, Можно Выбрать и Выбрать Storage Class for Controlling Data Representation in Generated Code.

Заменяя Математические функции и Операторы с Реализациями, которые требуют Выравнивания Данных - MATLAB®

Этот пример показывает, как разработать и использовать заменяющие записи библиотеки кода для целевых реализаций функции, которые требуют, чтобы данные были выровнены, чтобы оптимизировать производительность приложения. Сконфигурировать выравнивание данных для реализации функции:

  • Задайте требования выравнивания данных в записи таблицы. Можно задать выравнивание для аргументов функции реализации индивидуально или коллективно.

  • Задайте возможности выравнивания данных и синтаксис для вашего компилятора. Присоедините объект AlignmentSpecification к объекту TargetCharacteristics ключа реестра, заданного в вашем rtwTargetInfo.m файле.

Если внешне выделенные данные (например, аргументы функции точки входа) используются в операции, которая может быть заменена реализацией, которая требует выравнивания, используйте coder.dataAlignment директиву, чтобы задать выравнивание так, чтобы замена произошла.

Этот пример сконфигурирован, чтобы использовать GCC, Лязг или компилятор MSVC.

Создайте новую папку и скопируйте соответствующие файлы

Следующий код создает папку в вашей текущей рабочей папке (pwd). Новая папка будет содержать файлы, которые важны для этого примера. Если вы не хотите влиять на текущую папку (или если вы не можете сгенерировать файлы в этой папке), необходимо изменить рабочую папку.

Команда выполнения: создайте новую папку и скопируйте соответствующие файлы

coderdemo_setup('coderdemo_crlalign');
cleanupObj = {};
mlpath = addpath(fullfile(...
    matlabroot,'toolbox','coder','codegendemos','coderdemo_crlalign'));
cleanupObj{end+1} = onCleanup(@()path(mlpath));

Проверяйте выбранный компилятор

Этот пример сконфигурирован, чтобы использовать или GCC, Лязг или MSVC, чтобы скомпилировать сгенерированный код.

cc = rtwprivate('getMexCompilerInfo');
isDaDemoSupported = strcmpi(cc.comp.Manufacturer,'GNU') || ...
                    strcmpi(cc.comp.Manufacturer,'Apple') || ...
                    strcmpi(cc.comp.Manufacturer,'Microsoft');
if ~isDaDemoSupported
  recMsg = ['Use "mex -setup" to select either GCC, Clang,'...
      'or MSVC and restart this example'];
  warning(['Example %s is configured to use either GCC, Clang,'
      'or MSVC to compile the generated code. %s.'], mfilename,recMsg);
end

Установите опции MATLAB Coder

Настройте настройку, возражают и задают типы входного параметра функции.

cfg = coder.config('lib','ecoder',true);
cfg.GenerateReport = false;
cfg.LaunchReport = false;
cfg.VerificationMode = 'SIL';
cfg.CodeExecutionProfiling = true;

len = 400000;
args = {coder.typeof(single(0),[len,1]), ...
        coder.typeof(single(0))};
global g1;
g1 = single(zeros([len,1]));

Сгенерируйте код, пользующийся Заменяющей Библиотекой Кода В качестве примера SIMD

Чтобы видеть заменяющий табличный файл определения кода, посмотрите здесь.

RTW.TargetRegistry.getInstance('reset');

mcode_da16 = 'biased_sum_of_square_differences_da16';
cfg.CodeReplacementLibrary = 'SIMD Examples';
codegen('-config',cfg, mcode_da16,'-args',args,'-global',{'g1',g1});

Осмотрите сгенерированный код MATLAB Coder

После компиляции исследуйте сгенерированный исходный код.

Увеличение производительности от выравнивания данных

Сравните производительность нормального кода ANSI против более раннего сгенерированного кода, который использовал SIMD intrinsics.

% Generate ansi code
mcode_noda = 'biased_sum_of_square_differences';
cfg.CodeReplacementLibrary = 'None';
codegen('-config',cfg, mcode_noda,'-args',args,'-global',{'g1',g1});

% Run SIMD executable and collect execution profile information
coder.runTest('run_biased_ssd_da16',[mcode_da16,'_sil.',mexext])
pause(120);
clear([mcode_da16,'_sil']); % stop simulation
executionProfile_simd = getCoderExecutionProfile(mcode_da16);
idx_section = find(strcmp(mcode_da16,{executionProfile_simd.Sections.Name}),1);
avg_selftime_simd = executionProfile_simd.Sections(idx_section)...
    .TotalSelfTimeInTicks/executionProfile_simd.Sections(idx_section).NumCalls;

% Run ANSI executable and collect execution profile information
coder.runTest('run_biased_ssd',[mcode_noda,'_sil.',mexext])
pause(120);
clear([mcode_noda,'_sil']); % stop simulation
executionProfile_ansi = getCoderExecutionProfile(mcode_noda);
idx_section = find(strcmp(mcode_noda,{executionProfile_ansi.Sections.Name}),1);
avg_selftime_ansi = executionProfile_ansi.Sections(idx_section)...
    .TotalSelfTimeInTicks/executionProfile_ansi.Sections(idx_section).NumCalls;

% Compare execution profile results
barObj = bar([avg_selftime_ansi; ...
    avg_selftime_simd]);
axesObj = barObj.Parent;
figObj = axesObj.Parent;
axesObj.XTickLabel = {'ANSI SSD', 'SIMD SSD'};
axesObj.YLabel.String = 'Average Execution Time (Timer Ticks)';
axesObj.YLim = [min([0,avg_selftime_ansi,avg_selftime_simd]), ...
                max(avg_selftime_ansi,avg_selftime_simd)*1.3];

percent_perf_gain = ...
    100 * (avg_selftime_ansi-avg_selftime_simd)/avg_selftime_ansi;
annotation(figObj, 'textbox',axesObj.Position, ...
    'String',sprintf(...
    'Execution speed increased by %d%% on average',percent_perf_gain), ...
    'FontWeight', 'bold', 'FontSize', 12, 'HorizontalAlignment', 'center', ...
    'FitBoxToText','On');
### Starting SIL execution for 'biased_sum_of_square_differences_da16'
    To terminate execution: clear biased_sum_of_square_differences_da16_sil
    Execution profiling data is available for viewing. Open <a href="matlab:Simulink.sdi.view;">Simulation Data Inspector.</a>
    Execution profiling report available after termination.
### Stopping SIL execution for 'biased_sum_of_square_differences_da16'
    Execution profiling report: report(getCoderExecutionProfile('biased_sum_of_square_differences_da16'))

### Starting SIL execution for 'biased_sum_of_square_differences'
    To terminate execution: clear biased_sum_of_square_differences_sil
    Execution profiling data is available for viewing. Open <a href="matlab:Simulink.sdi.view;">Simulation Data Inspector.</a>
    Execution profiling report available after termination.
### Stopping SIL execution for 'biased_sum_of_square_differences'
    Execution profiling report: report(getCoderExecutionProfile('biased_sum_of_square_differences'))

Очистка

Удалите файлы и возвратитесь к исходной папке

Команда выполнения: Очистка

RTW.TargetRegistry.getInstance('reset');
cleanup

Похожие темы