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

Когда генератор кода производит код для математических функций:

  • Если выбран Support non-finite numbers опции модели, нефинитная проверка чисел генерируется равномерно для математических функций, без возможности задать, что нефинитная проверка чисел должна быть сгенерирована для некоторых функций, но не для других.

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

Можно использовать записи индивидуальной настройки библиотеки замещения кода (CRL) для:

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

  • Выборочно отключите инкрустацию математических функций. Это может увеличить удобочитаемость кода и уменьшить размер кода.

Функции, для которых поддерживаются эти индивидуальные настройки, включают следующее:

  • Только с плавающей точкой: atan2, copysign, fix, hypot, log, log10, round, sincos, и sqrt

  • Плавающее и целое число: abs, max, min, mod, rem, saturate, и sign

Общий рабочий процесс отключения проверки нефинитовых чисел и/или инкрустации заключается в следующем:

  1. Если можно отключить нефинитную проверку чисел для конкретной математической функции или если вы хотите отключить инкрустацию для конкретной математической функции и вместо этого сгенерировать вызов функции, можно скопировать следующий MATLAB® код функции в файл MATLAB со .m расширение имени файла, например crl_table_customization.m.

    function hTable = crl_table_customization
        
    % Create an instance of the Code Replacement Library table for controlling
    % function intrinsic inlining and nonfinite support
    
    hTable = RTW.TflTable;
    
    % Inline - true (if function needs to be inline)
    %          false (if function should not be inlined)
    % SNF (support nonfinite) - ENABLE (if non-finite checking should be performed)
    %                           DISABLE (if non-finite checking should NOT be performed)
    %                           UNSPECIFIED (Default behavior)
    
    % registerCustomizationEntry(hTable, ...
    %       Priority, numInputs, key, inType, outType, Inline, SNF);
    
    registerCustomizationEntry(hTable, ...
            100, 2, 'atan2', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'atan2', 'single', 'single', false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'sincos', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sincos', 'single', 'single', false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'double', 'double', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'single', 'single', true, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'int32',  'int32',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'int16',  'int16',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'int8',   'int8',   true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'integer','integer',true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'uint32', 'uint32', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'uint16', 'uint16', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'abs', 'uint8',  'uint8',  true, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 2, 'hypot', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'hypot', 'single', 'single', false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'log', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'log', 'single', 'double', false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'log10', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'log10', 'single', 'double', false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'double', 'double', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'single', 'single', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'int32',  'int32',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'int16',  'int16',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'int8',   'int8',   true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'uint32', 'uint32', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'uint16', 'uint16', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'uint8',  'uint8',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'min', 'integer','integer',true, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'double', 'double', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'single', 'single', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'int32',  'int32',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'int16',  'int16',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'int8',   'int8',   true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'uint32', 'uint32', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'uint16', 'uint16', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'uint8',  'uint8',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'max', 'integer','integer',true, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'single', 'single', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'int32',  'int32',  false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'int16',  'int16',  false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'int8',   'int8',   false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'uint32', 'uint32', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'uint16', 'uint16', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'mod', 'uint8',  'uint8',  false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'single', 'single', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'int32',  'int32',  false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'int16',  'int16',  false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'int8',   'int8',   false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'uint32', 'uint32', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'uint16', 'uint16', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 2, 'rem', 'uint8',  'uint8',  false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'round', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'round', 'single', 'single', false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'double', 'double', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'single', 'single', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'int32',  'int32',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'int16',  'int16',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'int8',   'int8',   true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'uint32', 'uint32', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'uint16', 'uint16', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'uint8',  'uint8',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 3, 'saturate', 'integer','integer',true, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'double', 'double',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'single', 'single',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'int32',  'integer', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'int16',  'integer', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'int8',   'integer', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'uint32', 'uint32',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'uint16', 'uint16',  true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'uint8',  'uint8',   true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sign', 'integer','integer', true, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'sqrt', 'double', 'double', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'sqrt', 'single', 'single', true, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'fix', 'double', 'double', false, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'fix', 'single', 'single', false, 'UNSPECIFIED');
    
    registerCustomizationEntry(hTable, ...
            100, 1, 'copysign', 'double', 'double', true, 'UNSPECIFIED');
    registerCustomizationEntry(hTable, ...
            100, 1, 'copysign', 'single', 'single', true, 'UNSPECIFIED');
  2. Чтобы уменьшить размер файла, можно удалить registerCustomizationEntry линии для функций, для которых допустимо поведение проверки нефинитных чисел и встраивания по умолчанию.

  3. Для каждой оставшейся записи,

    • Установите Inline аргумент в true если функция должна быть встроена или false если он не должен быть встроен.

    • Установите SNF аргумент в ENABLE если необходимо сгенерировать нефинитную проверку, DISABLE если нефинитная проверка не должна быть сгенерирована, или UNSPECIFIED для принятия поведения по умолчанию на основе настроек опций модели.

    Сохраните файл.

  4. Также можно выполнить быструю проверку синтаксической валидности записей таблицы индивидуальной настройки путем вызова файла определения таблицы в командной строке MATLAB (>> tbl = crl_table_customization). Исправьте отмеченные синтаксические ошибки.

  5. При необходимости просмотрите записи таблицы индивидуальной настройки в Code Replacement Viewer (>> crviewer(crl_table_customization)). Дополнительные сведения о просмотре таблиц замещения кода см. в разделе Выбор библиотеки замещения кода.

  6. Чтобы зарегистрировать эти изменения и отобразить их в выпадающем списке Code replacement library, расположенном на панели Code Generation > Interface диалогового окна Параметры конфигурации, сначала скопируйте следующий код функции MATLAB в образец файла rtwTargetInfo.m.

    Примечание

    В приведенном ниже примере укажите аргумент 'RTW' если для модели выбрана цель GRT, в противном случае опускает аргумент.

    function rtwTargetInfo(cm)
    % rtwTargetInfo function to register a code replacement library (CRL)
    
      % Register the CRL defined in local function locCrlRegFcn
      cm.registerTargetInfo(@locCrlRegFcn);
    
    end % End of RTWTARGETINFO
    
    
    % Local function to define a CRL containing crl_table_customization
    function thisCrl = locCrlRegFcn
    
      % Instantiate a CRL registry entry - specify 'RTW' for GRT
      thisCrl = RTW.TflRegistry('RTW');
    
      % Define the CRL properties
      thisCrl.Name = 'CRL Customization Example';
      thisCrl.Description = 'Example  of CRL Customization';
      thisCrl.TableList = {'crl_table_customization'};
      thisCrl.TargetHWDeviceType = {'*'};
      
    end % End of LOCCRLREGFCN

    Можно отредактировать Name поле, в котором указывается имя библиотеки, отображаемое в раскрывающемся списке Code replacement library. Кроме того, имя файла в TableList поле должно совпадать с именем файла, созданного вами на шаге 1.

    Чтобы зарегистрировать ваши изменения, с обоими файлами MATLAB, созданными вами, присутствующими в пути MATLAB, введите следующую команду в командной строке MATLAB:

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

  8. Откройте диалоговое окно Параметров конфигурации, перейдите в область Code Generation > Interface и используйте выпадающий список Code replacement library , чтобы выбрать запись замены кода, зарегистрированную вами на шаге 6, для примера, CRL Customization Example.

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