Данные переменного размера - это данные, размер которых может измениться во время выполнения. MATLAB ® поддерживает ограниченные и неограниченные данные переменного размера для создания кода. Ограниченные данные переменного размера имеют фиксированные верхние границы. Эти данные могут распределяться статически в стеке или динамически в куче. Неограниченные данные переменного размера не имеют фиксированных верхних границ. Эти данные должны быть распределены в куче. По умолчанию для генерации кода MEX и C/C + + включена поддержка данных переменного размера и динамическое выделение памяти для массивов переменного размера, размер которых превышает настраиваемый порог.
По умолчанию для ускорения кода MEX и C/C + + включена поддержка данных переменного размера. Параметры размера переменных изменяются в командной строке.
Создайте объект конфигурации для создания кода.
cfg = coder.mexconfig;
Установите EnableVariableSizing вариант:
cfg.EnableVariableSizing = false;
Использование -config , передать объект конфигурации в fiaccel :
fiaccel -config cfg foo
По умолчанию динамическое выделение памяти включено для массивов переменного размера, размер которых превышает настраиваемый порог. При отключении поддержки данных переменного размера также отключается динамическое выделение памяти. Параметры динамического выделения памяти можно изменить в командной строке.
Создайте объект конфигурации для ускорения кода. Например, для функции MEX:
mexcfg = coder.mexconfig;
Установите DynamicMemoryAllocation вариант:
| Настройка | Действие |
|---|---|
mexcfg.DynamicMemoryAllocation='Off'; | Динамическое выделение памяти отключено. Все данные переменного размера распределяются в стеке статически. |
mexcfg.DynamicMemoryAllocation='AllVariableSizeArrays'; | Динамическое выделение памяти включено для всех массивов переменного размера. Все данные переменного размера динамически распределяются в куче. |
mexcfg.DynamicMemoryAllocation='Threshold'; | Динамическое выделение памяти включено для всех массивов переменного размера, размер которых (в байтах) больше или равен значению, указанному с помощью Dynamic memory allocation threshold параметр. Массивы переменного размера, размер которых меньше этого порога, выделяются в стеке. |
При необходимости, если задано значение Dynamic memory allocation кому 'Threshold', конфигурирование Dynamic memory allocation threshold для точной настройки распределения памяти.
Использование -config , передать объект конфигурации в fiaccel:
fiaccel -config mexcfg foo
Вот базовый рабочий процесс, который генерирует MEX-код.
В редакторе MATLAB добавьте директиву компиляции. %#codegen в верхней части функции.
Эта директива:
Указывает, что предполагается создать код для алгоритма MATLAB
Включение проверки анализатора кода MATLAB для обнаружения потенциальных ошибок во время генерации кода
Устраните проблемы, обнаруженные анализатором кода.
В некоторых случаях анализатор кода MATLAB предупреждает, когда код присваивает данным фиксированный размер, но позже увеличивает данные, например, путем назначения или объединения в цикле. Если размер этих данных во время выполнения должен изменяться, эти предупреждения можно игнорировать.
Создание функции MEX с помощью fiaccel. Используйте следующие параметры командной строки:
-args {coder.typeof...} при наличии входных данных переменного размера
-report для создания отчета о создании кода
Например:
fiaccel -report foo -args {coder.typeof(0,[2 4],1)}
coder.typeof чтобы указать один вход переменного размера для функции foo. Первый аргумент, 0, указывает тип входных данных (double) и сложность (real). Второй аргумент, [2 4], указывает размер, матрицу с двумя размерами. Третий аргумент, 1, указывает, что входные данные имеют переменный размер. Верхняя граница равна 2 для первого размера и 4 для второго размера.Примечание
Во время компиляции, fiaccel обнаруживает переменные и поля структуры, изменяющие размер после их определения, и сообщает об этих появлениях как об ошибках. Кроме того, fiaccel выполняет проверку выполнения для генерации ошибок, когда данные превышают верхние границы.
Исправление ошибок несоответствия размеров:
| Причина: | Как исправить: | Для получения дополнительной информации: |
|---|---|---|
| Вы пытаетесь изменить размер данных после их блокировки. | Объявите переменные размеры данных. | См. раздел Диагностика и исправление ошибок несоответствия размеров. |
Исправление ошибок верхних границ
| Причина: | Как исправить: | Для получения дополнительной информации: |
|---|---|---|
| MATLAB не может определить или вычислить верхнюю границу | Укажите верхнюю границу. | См. раздел Определение верхних границ для массивов переменного размера и Диагностика и исправление ошибок несоответствия размеров. |
| MATLAB пытается вычислить верхнюю границу для неограниченных данных переменного размера. | Если данные являются неограниченными, включите динамическое выделение памяти. | См. раздел Управление динамическим распределением памяти |
Создание кода C/C + + с помощью fiaccel функция.
В этом примере используется функция uniquetol. Эта функция возвращает в векторе B версия входного вектора A, где элементы уникальны для внутри допуска tol друг друга. В векторе B, abs(B(i) - B(j)) > tol для всех i и j. Первоначально предположим, что входной вектор A может хранить до 100 элементов.
function B = uniquetol(A, tol)
A = sort(A);
B = A(1);
k = 1;
for i = 2:length(A)
if abs(A(k) - A(i)) > tol
B = [B A(i)];
k = i;
end
endДобавить %#codegen директива компиляции в верхней части функции:
function B = uniquetol(A, tol) %#codegen
A = sort(A);
B = A(1);
k = 1;
for i = 2:length(A)
if abs(A(k) - A(i)) > tol
B = [B A(i)];
k = i;
end
endАнализатор кода обнаруживает эту переменную B может изменить размер в for- цикл. Он выдает следующее предупреждение:
The variable 'B' appears to change size on every loop iteration. Consider preallocating for speed.
В этой функции вектор B должен расширяться по мере добавления значений из вектора A. Поэтому это предупреждение можно проигнорировать.
Для создания кода MEX используйте fiaccel функция.
Создание функции MEX для uniquetol:
T = numerictype(1, 16, 15);
fiaccel -report uniquetol -args {coder.typeof(fi(0,T),[1 100],1),coder.typeof(fi(0,T))}
Что означают эти параметры командной строки?
При выполнении этой команды возникает ошибка компилятора:
??? Size mismatch (size [1 x 1] ~= size [1 x 2]). The size to the left is the size of the left-hand side of the assignment.
Откройте отчет об ошибках и перейдите на вкладку Переменные.

Ошибка указывает на несоответствие размеров левой и правой сторон оператора назначения B = [B A(i)];. Назначение B = A(1) устанавливает размер B как скаляр фиксированного размера (1 x 1). Следовательно, конкатенация [B A(i)] создает вектор 1 x 2.
Чтобы устранить эту ошибку, объявите B является вектором переменного размера.
Добавить этот оператор в uniquetol функция:
coder.varsize('B');Он должен появиться раньше B используется (читается). Например:
function B = uniquetol(A, tol) %#codegen
A = sort(A);
coder.varsize('B');
B = A(1);
k = 1;
for i = 2:length(A)
if abs(A(k) - A(i)) > tol
B = [B A(i)];
k = i;
end
endФункция coder.varsize объявляет каждый экземпляр B в uniquetol чтобы иметь переменный размер.
Создайте код снова с помощью той же команды:
fiaccel -report uniquetol -args {coder.typeof(fi(0,T),[1 100],1),coder.typeof(fi(0,T))}В текущей папке, fiaccel генерирует функцию MEX для uniquetol названный uniquetol_mex и предоставляет ссылку на отчет о создании кода.
Щелкните ссылку Просмотр отчета.
В отчете о создании кода выберите закладку Переменные.

Размер переменной B является 1x:?, что указывает на переменный размер без верхних границ.
Запустите исходный алгоритм MATLAB и функцию MEX с одинаковыми входами для одного и того же числа итераций цикла и сравните их скорости выполнения.
Создайте входные данные правильного класса, сложности и размера для передачи в uniquetol Функции MATLAB и MEX.
x = fi(rand(1,90), T); tol = fi(0, T);
Запустить оригинал uniquetol функция в цикле и время, необходимое для выполнения 10 итераций цикла.
tic; for k=1:10, b = uniquetol(x,tol); end; tSim=toc
Запустите созданную функцию MEX с теми же входами для того же числа итераций цикла.
tic; for k=1:10, b = uniquetol_mex(x,tol); end; tSim_mex=toc
Сравните время выполнения.
r = tSim/tSim_mex
В этом примере показано, что функция MEX генерируется с помощью fiaccel значительно ускоряет выполнение алгоритма с фиксированной точкой.