Ускорение алгоритма MATLAB путем генерации MEX-функции

Можно использовать MATLAB® Coder™, чтобы сгенерировать MEX-функцию из кода MATLAB. MEX-функция является исполняемым файлом MATLAB. Это сгенерированный код, который можно вызвать из MATLAB. Работая в среде MATLAB, используйте MEX-функции, чтобы ускорить вычислительно интенсивные фрагменты вашего кода MATLAB. Сгенерируйте MEX-функцию из кода MATLAB при помощи приложения MATLAB Coder или при помощи codegen в командной строке MATLAB.

В этом руководстве вы используете MATLAB Coder codegen команда для генерации MEX-функции для функции MATLAB. Сначала вы генерируете MEX-функцию, которая может принимать только входы с фиксированным, предварительно присвоенным размером. Затем вы генерируете другую MEX-функцию, которая может принимать входы многих различных размеров.

Учебные файлы

Скопируйте файлы учебника из папки matlabroot\ help\toolbox\coder\examples\euclidean в локальную рабочую папку. Здесь, matlabroot - папка установки MATLAB, например C:\Program Files\MATLAB\R2019a. Чтобы скопировать эти файлы в текущую папку, запустите эту команду MATLAB:

copyfile(fullfile(matlabroot,'help','toolbox','coder','examples','euclidean'))
Локальная рабочая папка не может быть частной папкой или папкой @. Это руководство использует euclidean_data.mat, euclidean.m, test.m, test_2d.m, build_mex_fixed.m, и build_mex_variable.m файлы.

  • Файл данных MATLAB euclidean_data.mat содержит две части данных: одну точку в трехмерном евклидовом пространстве и набор нескольких других точек в трехмерном евклидовом пространстве. Более конкретно:

    • x является 3-by- 1 Вектор-столбец, который представляет точку в трехмерном евклидовом пространстве.

    • cb является 3-by- 216 массив. Каждый столбец в cb представляет точку в трехмерном евклидовом пространстве.

  • Файл MATLAB euclidean.m содержит функцию euclidean который реализует основной алгоритм в этом примере. Функция принимает x и cb в качестве входов. Он вычисляет евклидово расстояние между x и каждая точка в cb и возвращает следующие величины:

    • Область вектора-столбца y_min, что равно столбцу в cb который представляет точку, ближайшую к x.

    • Область вектора-столбца y_max, что равно столбцу в cb который представляет самую дальнюю от x точку.

    • 2мерный вектор idx который содержит индексы столбцов векторов y_min и y_max в cb.

    • 2мерный вектор distance который содержит вычисленные наименьшие и самые большие расстояния до x.

    function [y_min,y_max,idx,distance] = euclidean(x,cb)
    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx(1)=1;
    idx(2)=1;
    
    distance(1)=norm(x-cb(:,1));
    distance(2)=norm(x-cb(:,1));
    
    % Find the vector in cb with minimum distance to x
    % Find the vector in cb with maximum distance to x
    for index=2:size(cb,2)
        d=norm(x-cb(:,index));
        if d < distance(1)
            distance(1)=d;
            idx(1)=index;
        end
        if d > distance(2)
            distance(2)=d;
            idx(2)=index;
        end
    end
    
    % Output the minimum and maximum distance vectors
    y_min=cb(:,idx(1));
    y_max=cb(:,idx(2));
    
    end
  • Скрипт MATLAB test.m загружает файл данных euclidean_data.mat в рабочую область. Он вызывает функцию euclidean для вычисления y_min, y_max, idx, и distance. Затем скрипт отображает вычисленные величины в командной строке.

    Загрузка euclidean_data.mat - шаг предварительной обработки, который выполняется перед вызовом основного алгоритма. Отображение результатов является шагом постобработки.

    % Load test data 
    load euclidean_data.mat
    
    % Determine closest and farthest points and corresponding distances
    [y_min,y_max,idx,distance] = euclidean(x,cb);
    
    % Display output for the closest point
    disp('Coordinates of the closest point are: ');
    disp(num2str(y_min'));
    disp(['Index of the closest point is ', num2str(idx(1))]);
    disp(['Distance to the closest point is ', num2str(distance(1))]);
    
    disp(newline);
    
    % Display output for the farthest point
    disp('Coordinates of the farthest point are: ');
    disp(num2str(y_max'));
    disp(['Index of the farthest point is ', num2str(idx(2))]);
    disp(['Distance to the farthest point is ', num2str(distance(2))]);
  • Скрипт MATLAB test_2d.m является модификацией test.m для точек в двумерном евклидовом пространстве. Содержимое test_2d.m показаны ниже в руководстве, когда вы используете его, чтобы протестировать MEX-функцию для входов переменного размера.

  • Скрипты сборки build_mex_fixed.m и build_mex_variable.m содержат команды для генерации статических библиотек C из кода MATLAB, которые принимают входы фиксированного размера и переменного размера, соответственно. Содержимое этих скриптов показано позже в руководстве, когда вы генерируете код С

Совет

Можно сгенерировать код из функций MATLAB при помощи MATLAB Coder. Генерация кода из скриптов MATLAB не поддерживается.

Используйте тестовые скрипты, чтобы отделить шаги до и после обработки от функции, которая реализует основной алгоритм. Эта практика позволяет вам легко повторно использовать свой алгоритм. Вы генерируете код для функции MATLAB, реализующей основной алгоритм. Вы не генерируете код для тестового скрипта.

Сгенерируйте MEX-функцию для функции MATLAB

Запуск оригинального кода MATLAB

Запустите тестовый скрипт test.m в MATLAB. Выходные выходы отображаются y, idx, и distance.

Coordinates of the closest point are: 
0.8         0.8         0.4
Index of the closest point is 171
Distance to the closest point is 0.080374


Coordinates of the farthest point are: 
0  0  1
Index of the farthest point is 6
Distance to the farthest point is 1.2923

Сделайте код MATLAB подходящим для генерации кода

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

Определенные встроенные функции MATLAB и функции тулбокса, классы и системные объекты, поддерживаемые для генерации кода C/C + +, имеют определенные ограничения на генерацию кода. Эти ограничения и связанные с ними указания по применению перечислены в Extended Capabilities разделах соответствующих страниц с описанием. Для получения дополнительной информации смотрите Функции и Объекты, Поддерживаемые для Генерации кода C/C + +.

  1. Откройте euclidean.m в редакторе MATLAB. Индикатор сообщения Анализатор кода в правом верхнем углу редактора MATLAB зеленый. Анализатор не обнаружил ошибок, предупреждений или возможностей для улучшения кода.

  2. После объявления функции добавьте %#codegen директива:

    function [y,idx,distance] = euclidean(x,cb) %#codegen
    The %#codegen директива предлагает анализатору кода идентифицировать предупреждения и ошибки, характерные для генерации кода.

    Индикатор сообщения анализатора кода становится красным, что указывает на обнаруженные проблемы генерации кода.

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

    % Initialize minimum distance as distance to first element of cb
    % Initialize maximum distance as distance to first element of cb
    idx = ones(1,2);
    
    distance = ones(1,2)*norm(x-cb(:,1));

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

    Дополнительные сведения об использовании анализатора кода см. в разделе Проверка кода на ошибки и предупреждения.

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

  5. Чтобы запустить Генерацию кода Инструмента готовности, вызовите coder.screener функция из командной строки MATLAB:

    coder.screener('euclidean')

    Инструмент не обнаруживает проблем генерации кода для euclidean. Для получения дополнительной информации смотрите Генерация Кода Readiness Tool.

    Инструмент готовности генерации кода не поддерживается в Online™ MATLAB.

    Примечание

    Анализатор кода и инструмент подготовки генерации кода могут обнаружить не все проблемы генерации кода. После устранения ошибок или предупреждений, которые эти инструменты обнаруживают, сгенерируйте код с помощью MATLAB Coder, чтобы определить, имеет ли ваш код MATLAB другие проблемы с податливостью.

Теперь вы готовы скомпилировать код с помощью приложения MATLAB Coder. Здесь compilation относится к генерации кода C/C + + из вашего кода MATLAB.

Примечание

Компиляция кода MATLAB относится к генерации кода C/C + + из кода MATLAB. В других контекстах термин компиляция может означать действие компилятора C/C + +.

Определение входных типов

Поскольку C использует статическое типирование, генератор кода должен определить класс, размер и сложность всех переменных в файлах MATLAB во время генерации кода, также известного как время компиляции. Поэтому, когда вы генерируете код для файлов, необходимо задать свойства всех входных параметров в функции точки входа. entry-point function является функцией MATLAB верхнего уровня, из которой вы генерируете код.

Когда вы генерируете код при помощи codegen команда, используйте -args опция для задания выборочных входных параметров для функций точки входа. Генератор кода использует эту информацию, чтобы определить свойства входных параметров.

На следующем шаге вы используете codegen команда, чтобы сгенерировать файл MEX из функции точки входа euclidean.

Сгенерируйте и проверьте MEX-функцию

Скрипт сборки build_mex_fixed.m содержит команды, которые вы используете для генерации и проверки MEX-функции для euclidean.m. Чтобы подтвердить MEX-функцию, запустите тестовый скрипт test с вызовами функции MATLAB euclidean заменяется вызовами сгенерированной MEX-функции.

% Load the test data
load euclidean_data.mat
% Generate code for euclidean.m with codegen. Use the test data as example input. Validate MEX by using test.m.
codegen -report euclidean.m -args {x, cb} -test test
Обратите внимание, что:

  • По умолчанию codegen генерирует MEX-функцию с именем euclidean_mex в текущей папке.

  • The -report инструкции по опциям codegen чтобы сгенерировать отчет генерации кода, который можно использовать для отладки проблем генерации кода и проверить, что ваш код MATLAB подходит для генерации кода.

  • The -args опция задает выборочные входные параметры для функции точки входа euclidean. Генератор кода использует эту информацию, чтобы определить класс, размер и сложность входных параметров.

  • Вы используете -test опция запуска тестового файла test.m. Эта опция заменяет вызовы на euclidean в тестовом файле с вызовами для euclidean_mex.

Для получения дополнительной информации об опциях генерации кода см. codegen.

  1. Запустите скрипт сборки build_mex_fixed.m.

    Генератор кода производит MEX-функцию euclidean_mex в текущей рабочей папке.

    Выходные выходы:

    Code generation successful: View report.
    Running test file: 'test' with MEX function 'euclidean_mex'.
    Coordinates of the closest point are: 
    0.8         0.8         0.4
    Index of the closest point is 171
    Distance to the closest point is 0.080374
    
    
    Coordinates of the farthest point are: 
    0  0  1
    Index of the farthest point is 6
    Distance to the farthest point is 1.2923
    Этот выход соответствует выходу, которая была сгенерирована исходной функцией MATLAB и проверяет MEX-функцию.

  2. Чтобы просмотреть отчет генерации кода в средстве просмотра, нажмите View report .

    Если генератор кода обнаруживает ошибки или предупреждения во время генерации кода, отчет описывает проблемы и предоставляет ссылки на проблемный код MATLAB. См. «Отчеты генерации кода».

Совет

Используйте скрипт сборки, чтобы сгенерировать код в командной строке. Скрипт сборки автоматизирует серию команд MATLAB, которые вы неоднократно выполняете в командной строке, экономя время и устраняя входные ошибки.

Сгенерируйте MEX-функцию для входных параметров переменного размера

MEX-функция, которую вы сгенерировали для euclidean.m может принимать только те входы, которые имеют тот же размер что и выборка входы, которые вы задали во время генерации кода. Однако входные массивы в соответствующую функцию MATLAB могут быть любого размера. В этой части руководства вы генерируете MEX-функцию из euclidean.m который принимает входы переменного размера.

Предположим, что вам нужны размерности x и cb в сгенерированной MEX-функции, чтобы иметь следующие свойства:

  • Первая размерность обоих x и cb может варьироваться в размере до 3.

  • Второе измерение x является фиксированным и имеет значение 1.

  • Второе измерение cb может варьироваться в размере до 216.

Чтобы задать эти входные свойства, вы используете coder.typeof функция. coder.typeof(A,B,1) задает вход переменного размера с тем же классом и сложностью, что и A и верхние границы, заданные соответствующим элементом вектора size B. Используйте скрипт сборки build_mex_variable.m который использует coder.typeof для задания свойств входов переменного размера в сгенерированной MEX-функции.

% Load the test data
load euclidean_data.mat

% Use coder.typeof to specify variable-size inputs
eg_x=coder.typeof(x,[3 1],1);
eg_cb=coder.typeof(cb,[3 216],1);

% Generate code for euclidean.m using coder.typeof to specify
% upper bounds for the example inputs
codegen -report euclidean.m -args {eg_x,eg_cb}

Можно проверить, что новая MEX-функция euclidean_mex принимает входы размерностей, отличных от размерных параметров x и cb. Тестовый скрипт test_2d.m создает вход массивы x2d и cb2d которые являются двумерными версиями x и cb, соответственно. Затем вызывается функция MATLAB euclidean при использовании этих входных параметров.

% Load the test data
load euclidean_data.mat

% Create 2-D versions of x and cb
x2d=x(1:2,:);
cb2d=cb(1:2,1:6:216);

% Determine closest and farthest points and corresponding distances
[y_min,y_max,idx,distance] = euclidean(x2d,cb2d);

% Display output for the closest point
disp('Coordinates of the closest point are: ');
disp(num2str(y_min'));
disp(['Index of the closest point is ', num2str(idx(1))]);
disp(['Distance to the closest point is ', num2str(distance(1))]);

disp(newline);

% Display output for the farthest point
disp('Coordinates of the farthest point are: ');
disp(num2str(y_max'));
disp(['Index of the farthest point is ', num2str(idx(2))]);
disp(['Distance to the farthest point is ', num2str(distance(2))]);

Выполняемые test_2d.m формирует выход:

Coordinates of the closest point are: 
0.8         0.8
Index of the closest point is 29
Distance to the closest point is 0.078672


Coordinates of the farthest point are: 
0  0
Index of the farthest point is 1
Distance to the farthest point is 1.1357

Чтобы запустить тестовый скрипт test_2d.m с вызовами на euclidean заменен вызовами на euclidean_mex, использование coder.runTest.

coder.runTest('test_2d','euclidean')
Выходы совпадают с выходами, генерируемыми исходной функцией MATLAB. Это проверяет тот факт, что новая MEX-функция может принимать входы размерностей, отличных от размерностей x и cb.

Следующие шаги

ЦельДополнительная информация

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

Функции и объекты, поддерживаемые для генерации кода C/C + +

Сгенерируйте код C++ MEX

Генерация кода С++

Создавайте и редактируйте входные типы в интерактивном режиме

Создание и редактирование входных типов при помощи редактора типов кодеров

Оптимизируйте скорость выполнения или использование памяти сгенерированного кода

Стратегии оптимизации

Узнайте об отчете генерации кода

Отчеты генерации кода

Сгенерированные времена выполнения см. в покрытие кода и MEX-функции Профилировщика MATLAB

MEX-функции профиля при помощи Профилировщика MATLAB

См. также

| |