Почему MATLAB не требует дополнительной памяти?

Операция перестановки должна выводить на выходе другую матрицу, не нравится reshape, где данные не изменены, permute изменяет данных.

Однако, если вы проверяете использование памяти в многомерной перестановке, она такая же, как и используемая переменная. Итак, мой вопрос: как MATLAB выполняет эту перестановку, чтобы избежать использования дополнительной памяти?

Дополнительный вопрос: существует ли какой-либо сценарий, в котором MATLAB фактически использует дополнительную память?


Тестовый код:

function out=mtest() 
   out = ones(1e3,1e3,1e3); % Caution, 8Gb
   out=permute(out,[3 1 2]);
end 

Вызвать это следующим образом:

profile -memory on
a=mtest;
profreport

ПРЕДОСТЕРЕЖЕНИЕ, его 8 Гб данных.

Ответы

Ответ 1

Ваш аргумент ошибочен, потому что профилировщик памяти MATLAB не говорит вам правду!

Метод permute на самом деле создает вторую копию матрицы с перестановкой данных и возвращает ее...

Я просто пробовал это сам:

  • В Windows 10 я открыл "диспетчер задач" на вкладке "Производительность" с учетом графиков "памяти". Я также установил "скорость обновления" на "высокий", чтобы получить более точное временное разрешение.

  • У меня только 8 гигабайт ОЗУ на моем ноутбуке, поэтому, чтобы избежать трещин, я изменил вашу функцию как:

    function out = mtest()
        out = rand([1e3,5e2,5e2]);  % about 1.8 GB = 1e3*5e2*5e2*8/2^30
        out = permute(out, [3 2 1]);
    end
    
  • Затем я запускал функцию просто как:

    %clear a
    a = mtest();
    

    и просмотрел использование памяти; Он пошел от 1,8 гигабайтов в использовании и поднялся до 5,2, а затем быстро до 3,6 концерта. Это подтверждает, что была создана копия.

Я также повторил тест под perfmon.exe, который показал тот же шаблон:

perfmon

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

Хотя это не совсем лучший способ профилировать использование памяти (лучше использовать надлежащий профайлер памяти, например, Intel Inspector XE), в какой-то степени он показывает, что permute действительно не работает на месте.

Ответ 2

Это только предположение, поскольку я действительно не знаю, что permute делает под капотом.

  • Перенос измерений всегда можно выполнять как последовательность элементарных операций перестановки, где "элементарный" означает замену только двух измерений. Например, permute(x, [4 1 2 3]) эквивалентно этой последовательности элементарных операций перестановки (последовательность не уникальна):

    permute(..., [4 2 3 1]) %// interchange dims 1 and 4: we have dims [4 2 3 1]
    permute(..., [1 4 3 2]) %// interchange dims 2 and 4: we have dims [4 1 3 2]
    permute(..., [1 2 4 3]) %// interchange dims 3 and 4: we have dims [4 1 2 3]
    
  • Каждая из этих элементарных операций (замена двух измерений) по существу является транспозицией вдоль заданной плоскости многомерного массива, выполняемой неоднократно по всем другим измерениям.

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

Объяснение этих трех фактов показывает, что это возможно сделать без значительного объема дополнительной памяти. Однако это не может быть подход, фактически используемый Matlab.