Можно профилировать времена выполнения для MEX-функций, сгенерированных MATLAB® Coder™ при помощи профилировщика MATLAB. Профиль для сгенерированного кода показывает количество вызовов и время, проведенное для каждой строки соответствующей функции MATLAB. Используйте Профилировщик, чтобы идентифицировать строки кода MATLAB, которые производят сгенерированный код, которые занимают большую часть времени. Эта информация может помочь вам идентифицировать и исправить проблемы производительности рано в цикле разработки. Для получения дополнительной информации о профилировщике MATLAB смотрите profile
и Профиль, чтобы Улучшать Производительность (MATLAB).
Можно использовать профилировщика MATLAB со сгенерированной MEX-функцией. Также, если у вас есть тестовый файл, который вызывает вашу функцию MATLAB, можно сгенерировать MEX-функцию и профилировать ее за один шаг. Можно выполнить эти операции в командной строке или в приложении MATLAB Coder.
Использовать Профилировщик со сгенерированной MEX-функцией:
Включите профилирование MEX путем установки свойства объекта настройки EnableMexProfiling
на true
.
Также можно использовать codegen
с опцией -profile
.
Эквивалентной установкой в приложении MATLAB Coder является Enable execution profiling на шаге Generate.
Сгенерируйте файл MEX MyFunction_mex
.
Запустите профилировщика MATLAB и просмотрите Сводный отчет по профилированию, который открывается в отдельном окне.
profile on; MyFunction_mex; profile viewer;
Убедитесь, что вы не изменили или переместили исходный файл MATLAB MyFunction.m
. В противном случае Профилировщик не рассматривает MyFunction_mex
для профилирования.
Если у вас есть тестовый файл MyFunctionTest.m
, который вызывает вашу функцию MATLAB, вы можете:
Сгенерируйте MEX-функцию и профилируйте ее за один шаг при помощи codegen
с -test
и опциями -profile
. Если вы включили профилировщика MATLAB прежде, выключите его, прежде чем вы будете использовать эти две опции вместе.
codegen MyFunction -test MyFunctionTest -profile
Профилируйте MEX-функцию путем выбора Enable execution profiling на шаге Verify приложения. Если вы включили профилировщика MATLAB прежде, выключите его, прежде чем вы выполните это действие.
Вы используете Профилировщик, чтобы идентифицировать функции или строки кода MATLAB, которые производят сгенерированный код, которые занимают большую часть времени. Следующее является примером функции MATLAB, которая преобразовывает представление ее входных матриц A
и B
от главного строкой до главного столбцом размещения в одной из ее строк. Такое преобразование имеет долгое время выполнения для больших матриц. Предотвращение преобразования путем изменения, что конкретная строка делает функцию более эффективной.
Рассмотрите функцию MATLAB:
function [y] = MyFunction(A,B) %#codegen % Generated code uses row-major representation of matrices A and B coder.rowMajor; length = size(A,1); % Summing absolute values of all elements of A and B by traversing over the % matrices row by row sum_abs = 0; for row = 1:length for col = 1:length sum_abs = sum_abs + abs(A(row,col)) + abs(B(row,col)); end end % Calling external C function 'foo.c' that returns the sum of all elements % of A and B sum = 0; sum = coder.ceval('foo',coder.ref(A),coder.ref(B),length); % Returning the difference of sum_abs and sum y = sum_abs - sum; end
Сгенерированный код для этой функции использует главное строкой представление квадратных матриц A
и B
. Код сначала вычисляет sum_abs
(сумма абсолютных значений всех элементов A
и B
) путем пересечения по строке матриц строкой. Этот алгоритм оптимизирован для матриц, которые представлены в главном строкой размещении. Код затем использует coder.ceval
, чтобы вызвать внешнюю функцию C foo.c
:
#include <stdio.h> #include <stdlib.h> #include "foo.h" double foo(double *A, double *B, double length) { int i,j,s; double sum = 0; s = (int)length; /*Summing all the elements of A and B*/ for(i=0;i<s*s;i++) { sum += A[i] + B[i]; } return(sum); }
Соответствующий заголовочный файл C foo.h
:
#include "rtwtypes.h" double foo(double *A, double *B, double length);
foo.c
возвращает переменную sum
, которая является суммой всех элементов A
и B
. Производительность функционального foo.c
независима от того, представлены ли матрицы A
и B
в главных строкой или главных столбцом размещениях. MyFunction
возвращает различие sum_abs
и sum
.
Можно измерить уровень MyFunction
для больших входных матриц A
и B
, и затем оптимизировать его далее:
Включите профилирование MEX и сгенерируйте код MEX для MyFunction
. Запустите MyFunction_mex
для двух больших случайных матриц A
и B
. Просмотрите Сводный отчет по профилированию.
A = rand(20000); B = rand(20000); codegen MyFunction -args {A,B} foo.c foo.h -profile profile on; MyFunction_mex(A,B); profile viewer;
Отдельное окно открывает показ Сводного отчета по профилированию.
Сводный отчет по профилированию показывает общее время и сам время для файла MEX и его дочернего элемента, который является сгенерированным кодом для исходной функции MATLAB.
Под Именем функции щелкните по первой ссылке, чтобы просмотреть Детализированный отчет Профиля для сгенерированного кода для MyFunction
. Вы видите строки, где большая часть времени была проведена:
Строка, вызывая coder.ceval
занимает большую часть времени (21,152 с). Эта строка имеет самое долгое время выполнения, потому что coder.ceval
преобразовывает представление матриц A
и B
от главного строкой размещения до главного столбцом размещения прежде, чем передать их внешней функции C. Можно избежать этого преобразования при помощи дополнительного аргумента -layout:rowMajor
в coder.ceval
:
sum = coder.ceval('-layout:rowMajor','foo',coder.ref(A),coder.ref(B),length);
Сгенерируйте MEX-функцию и профилируйте снова использование измененного MyFunction
.
A = rand(20000); B = rand(20000); codegen MyFunction -args {A,B} foo.c foo.h -profile profile on; MyFunction_mex(A,B); profile viewer;
MyFunction
показывает, что строка, вызывая coder.ceval
теперь занимает только 0,456 с:Когда вы используете coder.const
, чтобы свернуть выражения в константы, он вызывает различие в покрытии кода между функцией MATLAB и MEX-функцией. Например, рассмотрите функцию:
function y = MyFunction %#codegen a = 1; b = 2; c = a + b; y = 5 + coder.const(c); end
При профилировании функции MATLAB MyFunction
показывает это покрытие кода в Детализированном отчете Профиля:
Однако профилируя MEX-функцию MyFunction_mex
показывает различное покрытие кода:
Строки 2, 3, и 4 не выполняются в сгенерированном коде, потому что вы свернули выражение c = a + b
в константу для генерации кода.
Этот пример использует пользовательское сворачивание выражения. Генератор кода иногда автоматически сворачивает определенные выражения, чтобы оптимизировать производительность сгенерированного кода. Такая оптимизация также заставляет покрытие MEX-функции отличаться от функции MATLAB.
codegen
| coder.MexCodeConfig
| coder.ceval
| coder.const
| coder.rowMajor
| profile