exponenta event banner

Интерфейс с основными данными строк в функциональном блоке MATLAB

Компоновка массива может иметь важное значение для интеграции, удобства использования и производительности. Simulink ® по умолчанию использует компоновку «основной столбец», как и функциональный блок MATLAB. Однако во многих устройствах, датчиках и библиотеках для своих данных используется макет массива с основными строками. Можно применить модель непосредственно к этим данным с помощью coder.ceval функция с основным макетом строки в функциональном блоке MATLAB.

Макет массива также может влиять на производительность. Многие алгоритмы обеспечивают более эффективный доступ к памяти для одной конкретной структуры массива.

Компоновка основных строк в моделировании и создании кода

Для блока MATLAB Function можно задать макет основного массива строки внутри блока. Эта спецификация выполняется на уровне функции и не изменяет макет массива модели вне функции. Формат массива, заданный в блоке MATLAB Function, применяется как к моделированию, так и к генерации кода C/C + +. См. раздел Указание макета массива в функциях и классах.

Для генерации кода C/C + + с помощью программного обеспечения Simulink Coder™ и Embedded Coder ® можно задать компоновку массива на уровне модели, которая поддерживается функциональными блоками MATLAB. Дополнительные сведения об управлении компоновкой массива на уровне модели см. в разделе Создание кода матриц и массивов (Simulink Coder). Настройка создания кода модели для компоновки массива не влияет на моделирование. См. раздел Компоновка массива (Simulink Coder). Примеры использования макета основной строки в функциональном блоке MATLAB для генерации кода см. в разделе Создание основного кода строки для модели, содержащей функциональный блок MATLAB (Simulink Coder).

Для блока MATLAB Function спецификация компоновки массива на уровне функции имеет приоритет над спецификацией компоновки массива модели. Однако для глобальных и постоянных переменных приоритет имеет спецификация макета массива модели.

Преобразования макета массива

По умолчанию MATLAB ® и Simulink хранят данные в основном формате столбца. Программа автоматически вставляет преобразования компоновки массива по мере необходимости при указании различных макетов массива в различных функциях и на различных границах.

Например, при моделировании модели или создании кода для модели, в которой используется компоновка «основной столбец», а модель содержит блок MATLAB Function, в котором используется компоновка «основная строка», программа преобразует входные данные блока в компоновку «основная строка», а выходные данные блока при необходимости обратно в компоновку «основная строка». Преобразования компоновки массива могут влиять на производительность. Дополнительные сведения о характеристиках производительности для макета массива см. в разделе Разработка кода для макета основного массива строк.

Компоновка массива и алгоритмическая эффективность

Для некоторых алгоритмов компоновка основных строк обеспечивает более эффективный доступ к памяти. Рассмотрим эту функцию для добавления двух матриц. Алгоритм выполняет сложение через явный обход строки и столбца.

function [S] = addMatrix(A,B) 
coder.rowMajor;
S = zeros(size(A));
for row = 1:size(A,1) 
   for col = 1:size(A,2)  
       S(row,col) = A(row,col) + B(row,col);
   end
end

При использовании этого кода в блоке MATLAB Function создание кода приводит к появлению кода C для функции:

... 
/* generated code for addMatrix using row-major */
for (row = 0; row < 20; row++) { 
  for (col = 0; col < 10; col++) {
      S[col + 10 * row] = A[col + 10 * row] + B[col + 10 * row];   
   }
} 
...

Массивы индексируются сгенерированным кодом по формуле:

[col + 10 * row]

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

Использование макета «основной столбец» для данных приводит к увеличению длины шага и снижению эффективности доступа к памяти. Чтобы увидеть это сравнение, рассмотрим созданный код C для addMatrix используется компоновка «основной столбец»:

... 
/* generated code for addMatrix using column-major */
for (row = 0; row < 20; row++) {
  for (col = 0; col < 10; col++) {
     S[row + 20 * col] = A[row + 20 * col] + B[row + 20 * col];  
  }
}
...

В макете «основной столбец» элементы столбца являются смежными в памяти в сгенерированном коде. Соседние элементы памяти разделены приращениями одной строки и индексируются по формуле:

[row + 20 * col]

Однако алгоритм выполняет итерацию по столбцам во внутреннем for-цикле. Поэтому основной C-код столбца должен выполнять шаг из 20 элементов для каждого последовательного доступа к памяти.

Компоновка массива, обеспечивающая наиболее эффективный доступ к памяти, зависит от алгоритма. Для этого алгоритма компоновка основных строк данных обеспечивает более эффективный доступ к памяти. Алгоритм проходит по строке данных за строкой. Таким образом, хранение основных строк является более эффективным.

Макет основной строки для N-мерных массивов

Для N-мерных массивов можно использовать макет основной строки. Когда массив хранится в макете основной строки, элементы последнего (крайнего правого) измерения или индекса являются смежными в памяти. В компоновке «основной столбец» элементы из первого (крайнего слева) измерения или индекса являются смежными.

Рассмотрим функцию-пример addMatrix3D, которая принимает трехмерные входные данные.

function [S] = addMatrix3D(A,B)
coder.rowMajor;
S = zeros(size(A));
for i = 1:size(A,1)
    for j = 1:size(A,2)
        for k = 1:size(A,3)
            S(i,j,k) = A(i,j,k) + B(i,j,k);
        end
    end
end
end

Генератор кода создает код C:

... 
/* row-major layout */
for (i = 0; i < 20; i++) {
    for (j = 0; j < 10; j++) {
        for (k = 0; k < 5; k++) {
            S[(k + 5 * j) + 50 * i] = A[(k + 5 * j) + 50 * i] 
                                      + B[(k + 5 * j) + 50 * i];
        }
    }
}
...

В макете основной строки смежные элементы памяти разделяются одиночными приращениями последнего индекса, k. Внутренний for-loop выполняет итерацию по смежным элементам, разделенным только одной позицией в памяти.

Удалить coder.rowMajor вызовите и создайте код C, который использует компоновку «основной столбец»:

... 
/* column-major layout */
for (i = 0; i < 20; i++) {
    for (j = 0; j < 10; j++) {
        for (k = 0; k < 5; k++) {
            S[(i + 20 * j) + 200 * k] = A[(i + 20 * j) + 200 * k]
                                        + B[(i + 20 * j) + 200 * k];
        }
    }
}
...

При компоновке «основной столбец» смежные элементы разделяются единичными приращениями первого индекса, i. Внутренний for-loop теперь выполняет итерацию по смежным элементам, разделенным 200 позициями в памяти. Большая длина шага может привести к снижению производительности из-за пропусков кэш-памяти.

Поскольку алгоритм выполняет итерацию по последнему индексу, kво внутреннем for-loop длина шага значительно больше для сгенерированного кода, который использует компоновку «основной столбец». Для этого алгоритма компоновка основных строк данных обеспечивает более эффективный доступ к памяти.

Определение формата массива в вызовах внешних функций

Для вызова внешних функций C/C + +, которые ожидают данных, сохраненных с определенным форматом, используйтеcoder.ceval с layout синтаксис. Если этот синтаксис не используется, предполагается, что входные и выходные данные внешних функций по умолчанию используют компоновку «основной столбец».

Рассмотрим внешнюю функцию C, предназначенную для использования основного макета строки. myCFunctionRM. Чтобы интегрировать эту функцию в код, вызовите функцию с помощью '-layout:rowMajor' или '-row' вариант. Этот параметр гарантирует, что входные и выходные массивы хранятся в основном порядке строк. Генератор кода автоматически вставляет преобразования компоновки массива по мере необходимости.

coder.ceval('-layout:rowMajor','myCFunctionRM',coder.ref(in),coder.ref(out)) 

В рамках функции MATLAB, использующей макет основной строки, можно попытаться вызвать внешнюю функцию, предназначенную для использования макета основной строки. В этом случае используйте '-layout:columnMajor' или '-col' вариант.

coder.ceval('-layout:columnMajor','myCFunctionCM',coder.ref(in),coder.ref(out)) 

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

function [E] = myMixedFn1(x,y)
%#codegen
coder.rowMajor; 
% specify type of return arguments for ceval calls
D = zeros(size(x)); 
E = 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 row-major order
coder.ceval('-layout:rowMajor','addMatrixRM', ...
    coder.rref(x),coder.rref(y),coder.wref(D));

% call C function that uses column-major order
coder.ceval('-layout:columnMajor','addMatrixCM', ...
    coder.rref(x),coder.rref(D),coder.wref(E));
end

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

 addMatrixRM.h

 addMatrixRM.c

 addMatrixCM.h

 addMatrixCM.c

См. также

| | | |

Связанные темы