За пределами генерации кода, MATLAB® использует упорядоченное по столбцам размещение по умолчанию. Технические требования размещения массивов не влияют на автономный код MATLAB. Чтобы протестировать КПД вашего сгенерированного кода или вашего блока MATLAB Function, создайте отдельные версии с упорядоченным по строкам размещением и упорядоченным по столбцам размещением. Затем сравните их эффективность.
Можно спроектировать код MATLAB, чтобы избежать потенциальной неэффективности, связанной с размещением массивов. Неэффективность может быть вызвана:
Преобразования между упорядоченным по строкам размещением и упорядоченным по столбцам размещением.
Одномерная или линейная индексация упорядоченных по строкам данных.
Изменение или перестановка упорядоченных по строкам данных.
Преобразования размещения массивов необходимы, когда вы смешиваете упорядоченные по строкам и упорядоченные по столбцам технические требования в том же коде или модели, или когда вы используете линейную индексацию на данных, которые хранятся в упорядоченном по строкам. Когда вы симулируете модель или генерируете код для модели, которая использует упорядоченный по столбцам, и это содержит блок MATLAB Function, который использует упорядоченный по строкам, затем программное обеспечение преобразует входные данные в упорядоченные по строкам и выходные данные назад к упорядоченному по столбцам по мере необходимости, и наоборот.
Неэффективность может быть вызвана функциями или алгоритмами, которые менее оптимизированы для данного выбора размещения массивов. Если функция или алгоритм более эффективны для различного размещения, можно осуществить то размещение путем встраивания его в другую функцию с a coder.rowMajor
или coder.columnMajor
вызвать.
Рассмотрите код для myMixedFn2
, который использует coder.ceval
передать данные с упорядоченным по строкам и упорядоченным по столбцам размещением:
function [B, C] = myMixedFn2(x,y) %#codegen % specify type of return arguments for ceval calls A = zeros(size(x)); B = zeros(size(x)); C = zeros(size(x)); % include external C functions that use row-major & column-major coder.cinclude('addMatrixRM.h'); coder.updateBuildInfo('addSourceFiles', 'addMatrixRM.c'); coder.cinclude('addMatrixCM.h'); coder.updateBuildInfo('addSourceFiles', 'addMatrixCM.c'); % call C function that uses column-major order coder.ceval('-layout:columnMajor','addMatrixCM', ... coder.rref(x),coder.rref(y),coder.wref(A)); % compute B for i = 1:numel(A) B(i) = A(i) + 7; end % call C function that uses row-major order coder.ceval('-layout:rowMajor','addMatrixRM', ... coder.rref(y),coder.rref(B),coder.wref(C)); end
Внешние файлы:
Объявите объект настройки, cfg
. Сгенерируйте код, который использует упорядоченное по строкам размещение при помощи -rowmajor
опция.
cfg = coder.config('lib'); cfg.HighlightPotentialRowMajorIssues = true; codegen myMixedFn2 -args {ones(20,10),ones(20,10)} -config cfg -launchreport -rowmajor
Подсвеченные проблемы отображены в отчете генерации кода, на вкладке Code Insights, под разделом Potential row major issues.
Неэффективность размещения массивов происходит здесь потому что:
Генератор кода должен преобразовать входные переменные x
и y
к упорядоченному по столбцам размещению прежде, чем передать их addMatrixCM
. Транспонирует должен быть вставлен в сгенерированный код.
Генератор кода должен транспонировать выходную переменную A
назад в упорядоченное по строкам размещение, потому что myMixedFn2
использует упорядоченное по строкам размещение.
Цикл for использует линейную индексацию, которая требует упорядоченных по столбцам данных. Генератор кода должен повторно вычислить линейную индексацию потому что переменные A
и B
хранятся в упорядоченном по строкам.
Генератор кода следует за MATLAB упорядоченная по столбцам семантика для линейной индексации. Для получения дополнительной информации о линейной индексации в MATLAB смотрите Индексацию массива.
Чтобы использовать линейную индексацию на упорядоченных по строкам данных, генератор кода должен сначала повторно вычислить представление данных в упорядоченном по столбцам размещении. Эта дополнительная обработка может замедлить эффективность. Чтобы повысить эффективность кода, избегайте использования линейной индексации на упорядоченных по строкам данных или используйте упорядоченное по столбцам размещение для кода, который использует линейную индексацию.
Например, рассмотрите функциональный sumShiftedProducts
, который принимает матрицу как вход и выводит скалярное значение. Функция использует линейную индексацию на входной матрице, чтобы подвести итог продукта каждого элемента матрицы со смежным элементом. Выходное значение этой операции зависит от порядка, в котором хранятся входные элементы.
function mySum = sumShiftedProducts(A) %#codegen mySum = 0; % create linear vector of A elements B = A(:); % multiply B by B with elements shifted by one, and take sum mySum = sum( B.*circshift(B,1) ); end
Для MATLAB Coder™, чтобы сгенерировать код, который использует упорядоченное по строкам размещение, введите:
codegen -config:mex sumShiftedProducts -args {ones(2,3)} -launchreport -rowmajor
Для входа в качестве примера рассмотрите матрицу:
D = reshape(1:6,3,2)'
который уступает:
D = 1 2 3 4 5 6
Если вы передаете эту матрицу как вход к сгенерированному коду, элементам A
хранятся в порядке:
1 2 3 4 5 6
В отличие от этого, потому что векторный B
получен линейной индексацией, она хранится в порядке:
1 4 2 5 3 6
Генератор кода должен вставить изменяющуюся операцию, чтобы перестроить данные из упорядоченного по строкам размещения для A
к упорядоченному по столбцам размещению для B
. Эта дополнительная операция уменьшает КПД функции для упорядоченного по строкам размещения. Неэффективность увеличивается с размером массива. Поскольку линейная индексация всегда использует упорядоченное по столбцам размещение, сгенерированный код для sumShiftedProducts
приводит к тому же выходному результату ли сгенерированный с упорядоченным по строкам размещением или упорядоченным по столбцам размещением.
В общем случае функции, которые вычисляют индексы или индексы также, используют линейную индексацию и приводят к результатам, соответствующим данным, хранимым в упорядоченном по столбцам размещении. Эти функции включают:
coder.ceval
| coder.columnMajor
| coder.rowMajor
| coder.isRowMajor
| coder.isColumnMajor