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