Jak uprościć i przyspieszyć program w MATLABie? [FILM]

Czy zdarzyło Ci się kiedyś, że Twój program realizujący stosunkowo proste obliczenia wykonywał się bardzo długo? A może jakaś pętla spowodowała, że MATLAB przestał reagować na polecenie Ctr+c?
Przyczyną może być niezoptymalizowany pod kątem obliczeń wektorowych program. Okazuje się bowiem, że klasyczne podejście do programowania znane z języków niższego poziomu, gdzie na przykład do kopiowania elementów musimy używać pętli, nie jest wskazane w produkcie MathWorksa. MATLAB jest zoptymalizowany pod kątem obliczeń macierzowo-wektorowych i wykorzystanie tej cechy umożliwia uzyskanie uproszczenia programu, a przede wszystkim skrócenie czasu obliczeń. Zapraszam do lektury wpisu oraz zobaczenia filmu na Youtube dotyczącego tego tematu, link do którego znajduje się na końcu posta.
Alokacja pamięci i wektoryzacja obliczeń

Aby lepiej zobrazować problem, rozpatrzmy prosty przykład. Zadanie polega na wygenerowaniu N=100000 równomiernie rozłożonych liczb z zakresu od 0 do 1. W pierwszym odruchu wielu programistów sięga po pętle for:

for k = 1 : N
    x1(k) = k/N; % x1 jest powiększane w każdej iteracji
end

Uzyskany czas obliczeń 0.01s.

W MATLABie nie jest to ani eleganckie ani efektywne obliczeniowo podejście. Powiększanie wektora lub macierzy o nowe elementy powoduje konieczność kopiowania całej zmiennej w nowy obszar pamięci. A to jest operacja czasochłonna. Jednak, jeżeli już używacie takiej struktury, to przed rozpoczęciem obliczeń należy zainicjować wektor, do którego będą wpisywane generowane wartości:

x1(1,N) = 0;
for k = 1 : N
    x1(k) = k/N;
end

Uzyskany czas obliczeń 0.001s, czyli 10 razy krócej niż w przypadku pierwszym.

Stosowanie pętli for do generowania elementów wektora nie jest jednak w MATLABie zalecane. Mamy tu do dyspozycji operator dwukropka, który jest zoptymalizowany pod kątem generacji wektorów. Jego użycie pozwala znacznie uprościć program oraz skrócić czas jego realizacji:

x3=[0.00001:0.00001:1];

Uzyskany czas obliczeń 0.0004s. To jest 25 razy szybciej niż w przypadku pierwszym!

Wyżej wymienione techniki nazywane są w MATLABie alokacją pamięci dla zmiennej oraz wektoryzacją obliczeń. Ich stosowanie umożliwia znaczące uproszczenie programu i przyspieszenie jego realizacji.

Wiarygodne czasy obliczeń

Przytoczone czasy realizacji obliczeń zostały wyznaczone za pomocą funkcji tic i toc. Ponieważ jednak na czas obliczeń może wpłynąć chwilowe obciążenie procesora przez inne procesy systemowe czy też programy działające w tle, to badanie danego fragmentu programu należy powtórzyć wielokrotnie, a za czas obliczeń przyjąć czas sumaryczny bądź wartość średnią z M powtórzeń programu. Badany program należy więc objąć dodatkową pętlą:

M = 1000; % liczba powtórzeń eksperymentu

tic
for p = 1 : M
    % Tutaj znajduje się badany program
end
toc

W ten sposób uzyskane wyniki, dla M=1000 powtórzeń są bardziej miarodajne i stabilne, niż dla jednego obiegu programu, który może zależeć od chwilowego obciążenia procesora. Dla tak skonstruowanego programu otrzymano następujące rezultaty:

Metoda 1: 11.00s
Metoda 2: 0.40s
Metoda 3: 0.06s

Jak widać korzyść ze stosowania alokacji pamięci i wektoryzacji w MATLABie jest ogromna i przynosi nawet kilkusetkrotne przyspieszenie czasu obliczeń!

Youtube

Jeżeli chcecie dowiedzieć się więcej na temat poprawnego pisania, efektywnych obliczeniowo programów zachęcam do obejrzenia tego filmu na moim kanale na Youtube. Pochwalcie się w komentarzach czy udało Wam się zoptymalizować Wasze programy!
Piotr Burnos

(Visited 491 times, 1 visits today)

2 komentarze do “Jak uprościć i przyspieszyć program w MATLABie? [FILM]”

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *