Управление инкрустацией для тонкой настройки эффективности и читаемости сгенерированного кода

Inlining является методом оптимизации, который заменяет вызов функции на содержимое (тело) этой функции. Инкрустация устраняет накладные расходы на вызов функции, тем самым улучшая скорость.

В зависимости от вашего приложения, слишком много встраивания кода может также иметь определенные недостатки:

  • Inlining может создать больший код C/C + + и снизить читаемость кода. Например, предположим, что вы вызываете определенную функцию foo много раз в вашем источнике MATLAB® код. Если генератор кода всегда встроен foo, размер сгенерированного кода увеличивается из-за foo inlined каждый раз, когда он вызывается. Однако для этого узлы вызовов должны быть другими. Для примера встраивание не приводит к большому размеру кода, если foo вызывается несколько раз внутри цикла.

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

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

Управление инкрустацией определенной функции MATLAB

Чтобы дать указание генератору кода либо всегда, либо никогда не вводить в строку определенную функцию MATLAB, используйте coder.inline('always') и coder.inline('never') директивы в теле этой функции. Дополнительные сведения об этих директивах см. в разделе coder.inline.

Управляйте инкрустацией при помощи настроек генерации кода

У вас могут быть различные требования к скорости и читаемости для кода, сгенерированного для функций, которые вы записываете, и кода, сгенерированного для MathWorks® функций. Некоторые настройки генерации кода позволяют вам отдельно контролировать поведение встраивания для этих двух частей сгенерированного кода основы и в контур между ними. Эти настройки применяются как к генерации кода MEX, так и к генерации автономного кода.

Параметр конфигурации кодаОписаниеОпции

В объекте строения кода: InlineBetweenUserFunctions

В приложении MATLAB Coder™: На вкладке All Settings Inline between user functions

Управляет поведением inlining во всех узлах вызова, где функция, которую вы написали, вызывает другую функцию, которую вы написали

'Always' | 'Speed' (по умолчанию) | 'Readability' | 'Never'

В объекте строения кода: InlineBetweenMathWorksFunctions

В приложении MATLAB Coder: На вкладке All Settings, Inline between MathWorks functions

Управляет инлайнинговым поведением на всех сайтах вызовов, где функция MathWorks вызывает другую функцию MathWorks

'Always' | 'Speed' (по умолчанию) | 'Readability' | 'Never'

В объекте строения кода: InlineBetweenUserAndMathWorksFunctions

В приложении MATLAB Coder: На вкладке All Settings, Inline between user and MathWorks functions

Управляет внутренним поведением на всех сайтах вызовов, где функция, которую вы написали, вызывает функцию MathWorks или функция MathWorks вызывает функцию, которую вы написали

'Always' | 'Speed' (по умолчанию) | 'Readability' | 'Never'

Описание опций:

  • 'Always': Всегда выполняет инкрустацию на сайте вызова.

  • 'Speed': Использует внутреннюю эвристику, чтобы определить, выполнять ли инкрустацию на сайте вызова. Эта настройка обычно приводит к высоко оптимизированному коду. Этот параметр является настройкой по умолчанию.

  • 'Readability': Почти никогда не вводит вызовы функций, кроме вызовов очень маленьких функций. Сохраняет модульность кода, не жертвуя слишком большой скоростью, когда это возможно. Результаты в высоко читаемом коде.

  • 'Never': Никогда не вводит вызовы функции. Приводит к максимальной читаемости. Этот параметр может значительно снизить эффективность сгенерированного кода.

Примечание

В некоторых случаях генератор кода может не строго следовать опции, которую вы выбираете для параметра inlining. Например, если тело функции MathWorks содержит coder.inline('never') директива и вы устанавливаете InlineBetweenMathWorksFunctions на 'Always'генератор кода отдает выбор coder.inline директива и не встраивает эту функцию. Для получения дополнительной информации смотрите Взаимодействие между различными элементами управления встраиванием.

Пример стратегии встраивания

Это пример стратегии встраивания, которая балансирует скорость и читаемость сгенерированного кода. Вы поручаете генератору кода выполнять эти действия одновременно:

  • Сохраните модульность в коде, который вы пишете для лучшей читаемости, даже если это снижает скорость сгенерированного кода. Для этого поведения задайте InlineBetweenUserFunctions на 'Readability'.

  • Сгенерируйте высоко оптимизированный код для функций MathWorks, даже если это приводит к менее читаемому коду, потому что вы с меньшей вероятностью смотрите эту часть своей основы кода. Для этого поведения задайте InlineBetweenMathWorksFunctions на 'Speed'.

  • В сгенерированном коде функционируют отдельные функции, которые вы записываете, и MathWorks так, чтобы сгенерированный код не выглядел сильно отличным от вашего кода MATLAB. Для этого поведения задайте InlineBetweenUserAndMathWorksFunctions на 'Readability'.

Взаимодействие между различными элементами управления встраиванием

  • coder.inline('always') или coder.inline('never') директива, помещенная в тело функции MATLAB, переопределяет эффект глобальных элементов управления встраиванием, включая codegen опции и настройки строения кода. Посмотрите coder.inline.

    Некоторые функции MathWorks включают вызов coder.inline директива, которая влияет на взаимодействие этих функций с глобальными параметрами встраивания. Например, если тело функции MathWorks содержит coder.inline('never') директива и вы устанавливаете InlineBetweenMathWorksFunctions на 'Always'генератор кода отдает выбор coder.inline директива и не встраивает эту функцию.

  • The -O disable:inline и -O enable:inline опции codegen команда переопределяет отдельные значения трех параметров конфигурации кода InlineBetweenUserFunctions, InlineBetweenMathWorksFunctions, и InlineBetweenUserAndMathWorksFunctions.

Пример: Управление инкрустацией на контуре между вашими функциями и функциями MathWorks ®

В этом примере показано, как контролировать поведение встраивания во всех узлах вызова, где функция, которую вы написали, вызывает функцию MathWorks или функция MathWorks вызывает функцию, которую вы написали.

Задайте функцию, которая вызывает функции MathWorks

Задайте функцию MATLAB useBessely который принимает двойной массив x как вход, обрабатывает входной массив при помощи bessely и возвращает массив того же типа и размера, что и x.

type useBessely.m
function out = useBessely(x)
out = x + bessely(3,x);
end

Сгенерируйте код с параметрами Inlining по умолчанию

Сгенерируйте статическую библиотеку C++ для useBessely функция. Задайте вход, который будет 1-by- 100 double тип. Используйте значения по умолчанию для параметров встраивания. Эти значения по умолчанию оптимизируют скорость сгенерированного кода. Используйте -c флаг, который предписывает генератору кода производить только исходный код, а не создавать исходный код.

codegen -c -lang:c++ -config:lib useBessely -args {zeros(1,100)} -report
Code generation successful: To view the report, open('codegen/lib/useBessely/html/report.mldatx').

Откройте отчет генерации кода и проверьте сгенерированный код. Заметьте, что отдельная функция C++ не была сгенерирована для функции MathWorks bessely. Генератор кода вставил код для bessely функция в useBessely C++ функцию, содержащуюся в файле useBessely.cpp.

Сгенерируйте код с измененными настройками Inlining

Задайте объект строения кода cfg для генерации статической библиотеки C++. Установите свойство InlineBetweenUserAndMathWorksFunctions на 'Never'. Эта настройка предписывает генератору кода разделить функцию, которую вы написали, и функции MathWorks в сгенерированном коде. В результате сгенерированный код С++ является менее эффективным, но более читаемым, чем встроенный код.

cfg = coder.config('lib');
cfg.TargetLang = 'C++';
cfg.InlineBetweenUserAndMathWorksFunctions = 'Never';

Сгенерируйте код при помощи cfg как объект строения кода. Задайте вход, который будет 1-by- 100 double тип. Используйте -c флаг, который предписывает генератору кода производить только исходный код, а не создавать исходный код.

codegen -c -config cfg useBessely -args {zeros(1,100)} -report
Code generation successful: To view the report, open('codegen/lib/useBessely/html/report.mldatx').

Откройте отчет генерации кода и проверьте сгенерированный код. Функция C++ useBessely теперь вызывает другую функцию C++ coder::bessely который содержит код, сгенерированный для функции MathWorks bessely. Как сброс, сгенерированный C++ useBessely функция выглядит аналогично MATLAB useBessely функция, которую вы написали.

type codegen/lib/useBessely/useBessely.cpp
//
// File: useBessely.cpp
//
// MATLAB Coder version            : 5.2
// C/C++ source code generated on  : 21-Apr-2021 01:23:20
//

// Include Files
#include "useBessely.h"
#include "bessely.h"
#include "rt_nonfinite.h"

// Function Definitions
//
// Arguments    : const double x[100]
//                creal_T out[100]
// Return Type  : void
//
void useBessely(const double x[100], creal_T out[100])
{
  coder::bessely(x, out);
  for (int i{0}; i < 100; i++) {
    out[i].re += x[i];
  }
}

//
// File trailer for useBessely.cpp
//
// [EOF]
//

См. также

| | | |

Похожие темы