Как MATLAB обрабатывает операции с подмассивами с точки зрения скорости и памяти - PullRequest
2 голосов
/ 08 мая 2011

У меня есть большие массивы, над которыми я делаю довольно простую линейную алгебру. Я добился хорошего ускорения за счет векторизации операций, но я хочу знать, как MATLAB обрабатывает подмассивы.

Я предварительно выделяю массивы, потому что они используются в различных операциях, а мои формулы длинные и требуют много разных массивов и подмассивов, поэтому читаемость считается, пока я все еще кодирую.

Например, простой случай:

Array = someBig2DArray;
soln = Array;
[len_x len_y] = size(Array);
A1 = Array(2:len_x-1, 2:len_y-1);
A2 = Array(1:len_x-2, 2:len_y-1);
A3 = Array(3:len_x, 2:len_y-1);

soln(2:len_x-1, 2:len_y-1) = (A1 - 2*A2 + A3)/2 

Недостатком использования этого метода является то, что у меня есть 3 дополнительных массива в основном того же размера, занимающих память.

В качестве альтернативы:

soln(2:len_x-1, 2:len_y-1) = (Array(3:len_x, 2:leny-1) - 2*Array(2:len_x-1, 2:len_y-1) + Array(1:len_x-2, 2:len_y-1))/2

Использует ли этот второй метод меньше памяти, жертвуя читабельностью? Или он фактически создает «временные» массивы и фактически использует примерно такой же объем памяти, но ненадолго? (Я приближаюсь к пределу моей системы ...)

Внутренне ли эти методы одинаковы по скорости, говоря о bigO и количестве операций?

Существуют ли способы уменьшения требований к памяти первого метода при сохранении читабельности?

Вот фрагмент из моего кода (на самом деле 1D в данном случае). Сначала я думал, что векторизация цикла for и использование обычно очень хороших матричных функций matlab ускорит процесс. Как оказалось, первый способ значительно быстрее. Почему?

for i = 3:len-1
    dSdx = sigma(i) - sigma(i-1) + ...
        0.25*(sigma(i+1) - sigma(i) - sigma(i-1) + sigma(i-2));
    ddSdx2 = sigma(i+1) - 2*sigma(i) + sigma(i-1);
    sigma_new(i) = sigma(i) + dT*(kappa*ddSdx2/h^2 - U*dSdx/h);
end

%This section replaces the for loop above
dSdx = sigma(3:len-1) - sigma(2:len-2) + 0.25*(sigma(4:len) ...
    - sigma(3:len-1) - sigma(2:len-2) + sigma(1:len-3));
ddSdx2 = sigma(4:len) - 2*sigma(3:len-1) + sigma(2:len-2);
sigma_new(3:len-1) = sigma(3:len-1) + dT*(kappa*ddSdx2/h^2 - U*dSdx/h);          

1 Ответ

2 голосов
/ 08 мая 2011

вы можете использовать tic и toc для определения времени ваших методов.Испытание ваших двух подходов (есть некоторые опечатки и несоответствия в назначениях, которые необходимо исправить), показывает, что второй подход примерно в 3,5 раза медленнее первого.

...