Можно профилировать времена выполнения для MEX-функций, сгенерированных MATLAB® Coder™ при помощи профилировщика MATLAB. Профиль для сгенерированного кода показывает количество вызовов и время, проведенное для каждой линии соответствующей функции MATLAB. Используйте Профилировщик, чтобы идентифицировать линии кода MATLAB, которые производят сгенерированный код, которые занимают большую часть времени. Эта информация может помочь вам идентифицировать и откорректировать проблемы эффективности рано в цикле разработки. Для получения дополнительной информации о профилировщике MATLAB смотрите profile
и профилируйте свой код, чтобы улучшать производительность.
Графический интерфейс Профилировщику не поддерживается в MATLAB Online™.
Можно использовать профилировщика 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
занимает много времени (16,914 с). Эта линия имеет значительное время выполнения потому что 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,653 с:Когда вы используете coder.const
чтобы свернуть выражения в константы, это вызывает различие в покрытии кода между функцией MATLAB и MEX-функцией. Например, рассмотрите функцию:
function y = MyFoldFunction %#codegen a = 1; b = 2; c = a + b; y = 5 + coder.const(c); end
Профилирование функции MATLAB MyFoldFunction
показывает это покрытие кода в Детализированном отчете Профиля:
Однако профилируя MEX-функцию MyFoldFunction_mex
показывает различное покрытие кода:
Линии 2, 3, и 4 не выполняются в сгенерированном коде, потому что вы свернули выражение c = a + b
в константу для генерации кода.
Этот пример использует пользовательское сворачивание выражения. Генератор кода иногда автоматически сворачивает определенные выражения, чтобы оптимизировать эффективность сгенерированного кода. Такая оптимизация также заставляет покрытие MEX-функции отличаться от функции MATLAB.
profile
| codegen
| coder.MexCodeConfig
| coder.rowMajor
| coder.ceval
| coder.const