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

Эта тема объясняет несколько методов, чтобы использовать память эффективно в MATLAB®.

Используйте соответствующее хранение данных

MATLAB предоставляет вам различные размеры классов данных, такие как double и uint8, таким образом, вы не должны использовать большие классы, чтобы сохранить ваши меньшие сегменты данных. Например, 7 Кбайтам требуется меньше памяти, чтобы сохранить 1 000 маленьких значений беззнаковых целых чисел с помощью uint8 класс, чем он делает с double.

Использование соответствующего числового класса

Числовой класс, который необходимо использовать в MATLAB, зависит от намеченных действий. Класс по умолчанию double дает лучшую точность, но требует 8 байтов за элемент памяти хранилищу. Если вы намереваетесь выполнить сложную математику, такую как линейная алгебра, необходимо использовать класс с плавающей точкой, такой как double или single. single класс требует только 4 байтов. Существуют некоторые ограничения на то, что можно сделать с single класс, но большинство Математических операций MATLAB поддерживается.

Если только необходимо выполнить простую арифметику, и вы представляете исходные данные как целые числа, можно использовать целочисленные классы в MATLAB. Следующее является списком числовых классов, требования к памяти (в байтах), и поддерживаемые операции.

Класс (тип данных)БайтыПоддерживаемые операции
single4Большая часть математики
double8Вся математика
logical1Логические/условные операции
int8, uint81Арифметика и некоторые простые функции
int16, uint162Арифметика и некоторые простые функции
int32, uint324Арифметика и некоторые простые функции
int64, int648Арифметика и некоторые простые функции

Сокращение суммы издержек, храня данные

Массивы MATLAB (реализованный внутренне как mxArrays) потребуйте, чтобы комната сохранила метаинформацию о данных в памяти, такой как тип, размерности и атрибуты. Это берет приблизительно 104 байта за массив. Эти издержки только становятся проблемой, когда у вас есть большое количество (например, сотни или тысячи) маленького mxArrays (например, скаляры). 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  

Вы видите, что этот массив требует, чтобы только приблизительно 4 Кбайта хранились столь же разреженные, но приблизительно 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);

   function setrowval(row, value)
   A(row,:) = value;
   end

setrowval(400, 0);
disp('The new value of A(399:401,1:10) is')
A(399:401,1:10)
end

Исправьте используемую память

Один простой способ увеличить объем памяти, который вы имеете в наличии, состоит в том, чтобы очистить большие массивы, которые вы больше не используете.

Сохранение ваших больших данных периодически к диску

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

Очистка старых переменных из памяти, когда больше не необходимый

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

a = rand(100e6,1)              % 800 MB array 
b = rand(100e6,1)              % New 800 MB array 
Error using rand
Out of memory. Type HELP MEMORY for your options.
 
clear a
a = rand(100e6,1)              % New 800 MB array 

Похожие темы