Разработайте свой код, чтобы избежать потенциальной неэффективности, связанной с размещением массивов. Неэффективность может быть вызвана:
Преобразования между главным строкой размещением и главным столбцом размещением.
Одномерная или линейная индексация главных строкой данных.
Изменение или перестановка главных строкой данных.
За пределами генерации кода MATLAB® использует главное столбцом размещение по умолчанию. Спецификации размещения массивов не влияют на автономный код MATLAB. Чтобы протестировать эффективность вашего кода, сгенерируйте, разделяют версии кода главным строкой размещением и главным столбцом размещением. Затем сравните их производительность.
Неэффективность может также быть вызвана функциями или алгоритмами, которые менее оптимизированы для данного выбора размещения массивов. Если функция или алгоритм более эффективны для различного размещения, можно осуществить то размещение путем встраивания его в другую функцию с вызовом coder.columnMajor
или coder.rowMajor
.
Рассмотрите код для 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, под Потенциальным разделом главных проблем строки.
Неэффективность размещения массивов происходит здесь потому что:
Генератор кода должен преобразовать входные переменные x
и y
к главному столбцом размещению прежде, чем передать их addMatrixCM
. Транспонирует должен быть вставлен в сгенерированный код.
Генератор кода должен транспонировать выходную переменную A
назад в главное строкой размещение, потому что myMixedFn2
использует главное строкой размещение.
Цикл for использует линейную индексацию, которая требует главных столбцом данных. Генератор кода должен повторно вычислить линейную индексацию, потому что переменные A
и B
сохранены в главном строкой.
Генератор кода следует за MATLAB главная столбцом семантика для линейной индексации. Для получения дополнительной информации о линейной индексации в 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
Сгенерируйте код, который использует главное строкой размещение:
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.isColumnMajor
| coder.isRowMajor
| coder.rowMajor