Эта тема объясняет несколько методов, чтобы использовать память эффективно в MATLAB®.
MATLAB предоставляет вам различные размеры классов данных, такие как double
и uint8
, таким образом, вы не должны использовать большие классы, чтобы сохранить ваши меньшие сегменты данных. Например, 7 Кбайтам требуется меньше памяти, чтобы сохранить 1 000 маленьких значений беззнаковых целых чисел с помощью uint8
класс, чем он делает с double
.
Числовой класс, который необходимо использовать в MATLAB, зависит от намеченных действий. Класс по умолчанию double
дает лучшую точность, но требует 8 байтов за элемент памяти хранилищу. Если вы намереваетесь выполнить сложную математику, такую как линейная алгебра, необходимо использовать класс с плавающей точкой, такой как double
или single
. single
класс требует только 4 байтов. Существуют некоторые ограничения на то, что можно сделать с single
класс, но большинство Математических операций MATLAB поддерживается.
Если только необходимо выполнить простую арифметику, и вы представляете исходные данные как целые числа, можно использовать целочисленные классы в MATLAB. Следующее является списком числовых классов, требования к памяти (в байтах), и поддерживаемые операции.
Класс (тип данных) | Байты | Поддерживаемые операции |
---|---|---|
single | 4 | Большая часть математики |
double | 8 | Вся математика |
logical | 1 | Логические/условные операции |
int8, uint8 | 1 | Арифметика и некоторые простые функции |
int16, uint16 | 2 | Арифметика и некоторые простые функции |
int32, uint32 | 4 | Арифметика и некоторые простые функции |
int64, int64 | 8 | Арифметика и некоторые простые функции |
Массивы MATLAB (реализованный внутренне как mxArrays
) потребуйте, чтобы комната сохранила метаинформацию о данных в памяти, такой как тип, размерности и атрибуты. Это берет приблизительно 104 байта за массив. Эти издержки только становятся проблемой, когда у вас есть большое количество (например, сотни или тысячи) маленького mxArrays
(e.g. Скаляры. whos
списки команд память, используемая переменными, но, не включают эти издержки.
Поскольку простые числовые массивы (включение того mxArray
) имейте наименее служебное, необходимо использовать их по мере возможности. Когда данные являются слишком комплексными, чтобы сохранить в простом массиве (или матрица), можно использовать другие структуры данных.
Массивы ячеек состоят из отдельного mxArrays
для каждого элемента. В результате массивы ячеек со многими маленькими элементами имеют большие издержки.
Структуры требуют подобной суммы издержек на поле. Структуры со многими полями и маленьким содержимым имеют большие издержки и должны избежаться. Большой массив структур с полями числового скаляра требует намного большей памяти, чем структура с полями, содержащими большие числовые массивы.
Также обратите внимание на это, в то время как MATLAB хранит числовые массивы в непрерывной памяти, дело обстоит не так для структур и массивов ячеек. Для получения дополнительной информации смотрите, Как MATLAB Выделяет Память.
При чтении данных из двоичного файла с fread
, это - распространенная ошибка, чтобы задать только класс данных в файле, а не класс данных использование MATLAB, если это находится в рабочей области. В результате double
по умолчанию используется, даже если вы читаете только 8-битные значения. Например,
fid = fopen('large_file_of_uint8s.bin', 'r'); a = fread(fid, 1e3, 'uint8'); % Requires 8k whos a Name Size Bytes Class Attributes a 1000x1 8000 double a = fread(fid, 1e3, 'uint8=>uint8'); % Requires 1k whos a Name Size Bytes Class Attributes a 1000x1 1000 uint8
Если ваши данные содержат много нулей, рассмотрите использование разреженных массивов, которые хранят только ненулевые элементы. Следующий пример сравнивает разреженные и полные требования устройства хранения данных:
A = eye(1000); % Full matrix with ones on the diagonal As = sparse(A); % Sparse matrix with only nonzero elements whos Name Size Bytes Class Attributes A 1000x1000 8000000 double As 1000x1000 24008 double sparse
Вы видите, что этот массив требует, чтобы только приблизительно 24 Кбайта хранились столь же разреженные, но приблизительно 8 Мбайт как полная матрица. В общем случае для разреженного двойного массива с nnz
ненулевые элементы и ncol
столбцы, требуемая память:
16 * nnz
+ 8 * ncol
+ 8 байтов (на 64-битной машине)
Обратите внимание на то, что MATLAB поддерживает больше всего, но не все, математические операции на разреженных массивах.
Можно значительно уменьшать объем памяти, требуемый путем предотвращения создания ненужных временных копий данных.
Старайтесь не создавать большие временные переменные, и также сделайте его практикой, чтобы очистить временные переменные, когда они больше не будут необходимы. Например, этот код создает массив нулей, сохраненных как временная переменная A
, и затем преобразует A
к с одинарной точностью:
A = zeros(1e6,1); As = single(A);
Это использует память более эффективно, чтобы использовать одну команду, чтобы сделать обе операции:
A = zeros(1e6,1,'single');
Используя repmat
функция, предварительное выделение массивов, и for
циклы являются другими способами работать над недвойными данными, не требуя временного хранения в памяти.
При работе с большими наборами данных, иметь в виду, что MATLAB делает временную копию входной переменной, если вызванная функция изменяет свое значение. Это временно удваивает память, требуемую сохранить массив, который заставляет MATLAB генерировать ошибку, если достаточная память не доступна.
Один способ использовать меньше памяти в этой ситуации состоит в том, чтобы использовать вложенные функции. Вложенная функция совместно использует рабочую область всех внешних функций, предоставляя доступ к вложенной функции к данным за пределами его обычного осциллографа. В примере, показанном здесь, вложенная функция setrowval
имеет прямой доступ к рабочей области внешнего функционального myfun
, создание его ненужный, чтобы передать копию переменной в вызове функции. Когда setrowval
изменяет значение A
, это изменяет его в рабочей области функции вызова. Нет никакой потребности использовать дополнительную память, чтобы содержать отдельный массив для функции, вызванной, и также нет никакой потребности возвратить модифицированное значение A
:
function myfun A = magic(500); setrowval(400,0) disp('The new value of A(399:401,1:10) is') A(399:401,1:10) function setrowval(row,value) A(row,:) = value; end end
Один простой способ увеличить объем памяти, который вы имеете в наличии, состоит в том, чтобы очистить большие массивы, которые вы больше не используете.
Если ваша программа генерирует очень большие объемы данных, рассмотрите запись данных к диску периодически. После сохранения того фрагмента данных используйте clear
функция, чтобы удалить переменную из памяти и продолжить генерацию данных.
Когда вы работаете с очень большим набором данных неоднократно или в интерактивном режиме, очищаете старую переменную сначала, чтобы сделать пробел для новой переменной. В противном случае MATLAB требует временного хранения равного размера прежде, чем заменить переменную. Например,
a = rand(1e5); b = rand(1e5); Out of memory. More information clear a a = rand(1e5); % New array