По умолчанию генератор кода использует одномерную индексацию для массивов. Генератор кода создает одномерные массивы в коде C/C++ для N-мерных массивов в коде MATLAB®. Можно использовать N-мерную индексацию, чтобы улучшить удобочитаемость и адаптировать интерфейс к сгенерированному коду. Например, трехмерный массив MATLAB:
A = zeros(2,4,6)
становится:
A[48]
в сгенерированном коде C/C++, по умолчанию. Исходные данные размерности для массива не сохраняются. С N-мерной индексацией генератор кода производит:
A[6][4][2]
Порядок индексов инвертируется, потому что MATLAB генерирует код, который использует размещение главного массива столбца по умолчанию. Чтобы переключить порядок индексов, можно включить размещение главного массива строки.
Преобразование N-мерного массива к одной размерности также называется выравниванием массивов. В памяти компьютера все данные хранятся с точки зрения одномерных массивов. Выбор индексации не изменяет результаты вычисления. Однако, если ваш код имеет вводы или выводы, которые являются массивами, интерфейс к вашему сгенерированному коду может измениться.
Включить N-мерную индексацию:
Используйте опцию -preservearraydims
:
codegen foo -preservearraydims
Установите свойство PreserveArrayDimensions
для своего объекта настройки генерации кода к true
. Например:
cfg = coder.config('lib'); cfg.PreserveArrayDimensions = true; codegen foo -config cfg
Включить N-мерную индексацию из MATLAB Coder™App:
Перейдите к Сгенерировать Кодовой странице в рабочем процессе генерации кода.
Откройте диалоговое окно Generate путем нажатия на стрелку Generate.
Нажмите More Settings.
На вкладке Memory установите флажок измерений массива Заповедника.
N-мерная индексация может облегчить для вас прослеживать ваш сгенерированный код C/C++ до вашего кода MATLAB. Генератор кода сохраняет размерности исходных массивов, вместо того, чтобы преобразовать массивы в одну размерность. Кроме того, можно задать главное строкой размещение, чтобы сделать внешний вид кода еще более интуитивным.
Считайте функцию MATLAB addMatrices
, который добавляет две матрицы, поэлементно:
function sum = addMatrices(A,B) %#codegen sum = coder.nullcopy(A); for row = 1:size(A,1) for col = 1:size(A,2) sum(row,col) = A(row,col) + B(row,col); end end
Сгенерируйте код для addMatrices
так, чтобы это работало с 2 4 массивами. Включите N-мерную индексацию и размещение главного массива строки:
cfg = coder.config('lib'); cfg.PreserveArrayDimensions = true; cfg.RowMajor = true; codegen addMatrices -args {ones(2,4),ones(2,4)} -config cfg -launchreport
Генерация кода производит код с явной двумерной индексацией массива:
/* N-d indexing on, row-major on */ void addMatrices(double A[2][4], double B[2][4], double sum[2][4]) { int row; int col; for (row = 0; row < 2; row++) { for (col = 0; col < 4; col++) { sum[row][col] = A[row][col] + B[row][col]; } } }
Сгенерированный код для addMatrices
использует ту же двумерную индексацию как оригинальный код MATLAB. Можно легко анализировать сгенерированный код по сравнению с исходным алгоритмом. Чтобы понять, как использовать главное строкой размещение, смотрите, Генерируют Код Который Размещение Главного массива строки Использования.
Выбор размещения массивов влияет на внешний вид N-мерной индексации. Например, сгенерируйте код для функции addMatrices
, использующей размещение главного массива столбца:
cfg.RowMajor = false; codegen addMatrices -args {ones(2,4),ones(2,4)} -config cfg -launchreport
Генерация кода производит этот код С:
/* N-d indexing on, row-major off */ void addMatrices(double A[4][2], double B[4][2], double sum[4][2]) { int row; int col; for (row = 0; row < 2; row++) { for (col = 0; col < 4; col++) { sum[col][row] = A[col][row] + B[col][row]; } } }
Матрицы ввода и вывода в коде С, транспонирует исходных матриц MATLAB. Чтобы понять почему, рассмотрите, как массивы представлены в памяти компьютера. Язык MATLAB использует главное столбцом размещение по умолчанию, где элементы от первой (крайней левой) размерности или индекса непрерывны в памяти. C использует размещение главного массива строки по умолчанию, где элементы от последней (самой правой) размерности или индекса непрерывны. Чтобы сохранить исходную смежность элемента, генератор кода должен инвертировать порядок измерений массива.
Например, в этом случае, если вы задаете матрицу MATLAB A
как:
A=reshape(1:8,2,4)
или
A = 1 3 5 7 2 4 6 8
затем, потому что MATLAB использует главное столбцом размещение, данные внутренне сохранен в порядке:
A(:)' = 1 2 3 4 5 6 7 8
В коде С необходимо транспонировать исходные данные, для этого примера, вызвать его AA
:
AA = {{1, 2}, {3, 4}, {5, 6}, {7, 8}};
достигнуть списка элементов данных с тем же порядком внутренней памяти. Другими словами, массив C должен быть 4 2. (Можно получить эквивалентный порядок устройства хранения данных путем определения массива как 2 4 с AA = {{1, 2, 3, 4}, {5, 6, 7, 8}}
. Однако получение этого порядка требует, чтобы руководство изменилось или перестановка данных.)
Выбор размещения массивов влияет только на внутреннее представление данных и не изменяет вычислительные или алгоритмические результаты. Чтобы сохранить интуитивный внешний вид массивов MATLAB в сгенерированном коде, используйте N-мерную индексацию с размещением главного массива строки. Обратите внимание на то, что главное строкой размещение может влиять на эффективность вашего сгенерированного кода. Для получения дополнительной информации смотрите Дизайн Кода для Размещения Главного массива строки.
Рассмотрите другие аспекты N-мерной индексации. Генератор кода всегда производит одномерные массивы для N-мерных векторов, даже когда вы задаете N-мерную индексацию. Например, если вы генерируете код для вектора MATLAB:
A = zeros(1,10)
или
A = zeros(1,10,1)
получившиеся массивы C/C++ сохранены как:
A[10]
N-мерная индексация также применяется к массивам и структурам. Например, если вы объявляете структуры в своем коде как:
x = struct('f1', ones(2,3)); coder.cstructname(x,'myStruct1'); y = struct('f2', ones(1,6,1)); coder.cstructname(y,'myStruct2');
затем сгенерированный код содержит определения структуры:
typedef struct { double f1[2][3]; } myStruct1; typedef struct { double f2[6]; } myStruct2;
Избегайте линейной индексации на N-мерных массивах. Линейная индексация происходит, например, когда вы используете оператор двоеточия:
A(:)
Чтобы применить линейную индексацию, генератор кода должен бросить N-мерный массив в одномерный массив. Операции кастинга делают ваш код более комплексным для генератора кода, чтобы анализировать. Эта увеличенная сложность может препятствовать способности генератора кода оптимизировать для производительности.
Наконец, отметьте следующее:
Можно использовать N-мерную индексацию для массивов любого типа данных.
Только массивы фиксированного размера, и не массивы переменного размера, могут использовать N-мерную индексацию.
codegen
| coder.cstructname
| изменение