Проект кода для упорядоченного по строкам размещения массивов

За пределами генерации кода MATLAB® использует упорядоченное по столбцам размещение по умолчанию. Спецификации размещения массивов не влияют на автономный код MATLAB. Чтобы протестировать КПД вашего сгенерированного кода или вашего блока MATLAB Function, создайте отдельные версии с упорядоченным по строкам размещением и упорядоченным по столбцам размещением. Затем сравните их производительность.

Можно спроектировать код MATLAB, чтобы избежать потенциальной неэффективности, связанной с размещением массивов. Неэффективность может быть вызвана:

  • Преобразования между упорядоченным по строкам размещением и упорядоченным по столбцам размещением.

  • Одномерная или линейная индексация упорядоченных по строкам данных.

  • Изменение или перестановка упорядоченных по строкам данных.

Преобразования размещения массивов необходимы, когда вы смешиваете упорядоченные по строкам и упорядоченные по столбцам спецификации в том же коде или модели, или когда вы используете линейную индексацию на данных, которые хранятся в упорядоченном по строкам. Когда вы симулируете модель или генерируете код для модели, которая использует упорядоченный по столбцам, и это содержит блок MATLAB Function, который использует упорядоченный по строкам, затем программное обеспечение преобразует входные данные в упорядоченные по строкам и выходные данные назад к упорядоченному по столбцам по мере необходимости, и наоборот.

Неэффективность может быть вызвана функциями или алгоритмами, которые менее оптимизированы для данного выбора размещения массивов. Если функция или алгоритм более эффективны для различного размещения, можно осуществить то размещение путем встраивания его в другую функцию с 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

Внешние файлы:

 addMatrixRM.h

 addMatrixRM.c

 addMatrixCM.h

 addMatrixCM.c

Объявите объект настройки, 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 смотрите Индексацию массива (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 приводит к тому же выходному результату ли сгенерированный с упорядоченным по строкам размещением или упорядоченным по столбцам размещением.

В общем случае функции, которые вычисляют индексы или индексы также, используют линейную индексацию и приводят к результатам, соответствующим данным, хранимым в упорядоченном по столбцам размещении. Эти функции включают:

Смотрите также

| | | |

Похожие темы