Programowanie w jzyku Matlab Optymalizacja czasowa kodu Mfile
Programowanie w języku Matlab Optymalizacja czasowa kodu
M-file Profiler - uzyskuje się informację m. in. o czasie i liczbie wykonań poszczególnych fragmentów kodu - sposób użycia: >> profile on, profile clear >> badany kod >> profile report
Dane dostarczone przez M-file Profiler - badana funkcja: function result = example 1(Count) for k = 1: Count result(k) = sin(k/50); if result(k) < -0. 9 result(k) = gammaln(k); end - środowisko Matlab 7. 5. 0. 342 - komputer PC z procesorem Pentium 4, 2. 8 GHz, 2 GB RAM, system operacyjny Windows 2000 z Service Pack 4 - funkcja wywołana raz, z argumentem Count = 5000
Sposoby optymalizacji czasowej • • odpowiednie użycie danych, stosowanie konstrukcji, których działanie przyspiesza JIT-Accelerator, wektoryzacja kodu, inne.
Odpowiednie użycie danych • rezerwacja pamięci na tablicę o znanych wymiarach function result = example 1(Count) result = zeros(1, Count); for k = 1: Count result(k) = sin(k/50); if result(k) < -0. 9 result(k) = gammaln(k); end % 0. 002 s • odpowiedni dobór typu liczb – operacja na liczbach całkowitych są wykonywane szybciej niż na liczbach rzeczywistych
• unikanie tworzenia niepotrzebnych zmiennych 1. 2. function y = modfun 1(x) function x = modfun 2(x) y = 1. 2*x; x = 1. 2*x; Czas wykonania dla tablicy o wymiarach 3000 x 3000: 1. 2. 731 s 2. 0. 219 s • zachowanie typów zmiennych
• przetwarzanie elementów tablic po kolumnach 1. for r = 1: N for c = 1: N 2. for c = 1: N for r = 1: N if x(r, c) > 0 y(r, c) = x(r, c); end end end Czas wykonania przy: N = 3000, 4497523 elementach niezerowych i wcześniejszej rezerwacji pamięci na tablicę y: 1. 3. 11 s 2. 0. 755 s
Jeśli algorytm na to pozwala – traktować tablicę jako wektor i stosować indeksowanie liniowe for k = 1: N*N if x(k) > 0 y(k) = x(k); end Czas wykonania: 0. 672 s.
Stosowanie konstrukcji, których działanie przyspiesza JIT-Accelerator Od wersji 6. 5 Matlab zawiera tzw. JIT-Accelerator, który znacznie skraca czas wykonywania kodu. Trzeba jednak przestrzegać kilku zasad: 1. zmienne muszą być typu: double, complex, logical, char, int 8, uint 8, int 16, uint 16, int 32, uint 32; nie są przyspieszane operacje na: komórkach, strukturach, tablicach rzadkich oraz z użyciem uchwytów do funkcji, 2. tablice mogą mieć co najwyżej trzy wymiary, 3. nie może następować zmiana rozmiaru ani typu zmiennej, 4. używane funkcje mogą być tylko funkcjami wbudowanymi Matlaba, 5. wynik wyrażenia w instrukcjach: if, switch i while musi być skalarem, 6. zmienna sterująca pętli for musi przyjmować wartości skalarne, 7. wszystkie instrukcje w pętli muszą być napisane zgodnie z podanymi zasadami.
Wektoryzacja kodu Wektoryzacja - zastępowanie, o ile to możliwe, pętli, w których przetwarzane są pojedyncze elementy tablic, odpowiednimi operacjami tablicowymi. Przy wektoryzacji wykorzystywane są: - operator dwukropka – do tworzenia tablic, przy odwołaniach do całych wierszy i kolumn oraz fragmentów tablic - indeksowanie logiczne przy odwołaniach do elementów tablic, - arytmetyczne operatory tablicowe, - standardowe funkcje operujące na tablicach np. sum, prod, any, all, find, sort. Po wprowadzeniu JIT-Accelerator wektoryzacja już nie zawsze przynosi korzyści – hasło , , życie jest za krótkie, żeby je spędzać na pisaniu pętli for’’ straciło na znaczeniu.
Utworzenie tablicy z wartościami funkcji cosinus dla t od 0 do 100 radianów, zmieniającym się co 0. 0 1. k = 0; 2. y = cos(0: . 01: 100); for t = 0: . 01: 100 k = k + 1; y(k) = cos(t); end Czas wykonania: 1. 0. 209 s bez rezerwacji pamięci na tablicę wyników, 0. 115 s z rezerwacją 2. 0. 024 s
Utworzenie tablicy y z elementów tablicy x, przy czym elementy nieujemne mają pozostać, pozostałe mają być zastąpione 0 2. 1. for c = 1: N for r = 1: N if x(r, c) > 0 y = zeros(N); t = x > 0; y(t) = x(t); y(r, c) = x(r, c); end end Czas wykonania (warunki pomiaru jak wcześniej): 1. 0. 755 s 2. 0. 823 s
Obliczenie sumy ciągu: 1 + 1/2 + 1/3 +. . . + 1/n 1. suma = 0; for k = 1: n suma = suma + 1/k; end Czas wykonania przy n = 100000: 1. 0. 001 s 2. 0. 006 s 2. suma = sum(1. /(1: n));
Obliczenie sumy elementów leżących na przekątnej głównej tablicy 1. m = size(A, 1); 2. suma = sum(diag(A)); suma = 0; for k = 1: m suma = suma + A(k, k); end Czas wykonania przy tablicy A o wymiarach 1000 x 1000: 1. 0. 00013 s 2. 0. 00028 s
Inne sposoby: • napisanie fragmentów kodu w języku C lub Fortran i korzystanie z ich skompilowanych wersji zapisanych w mex-plikach, • korzystanie z funkcji zaprojektowanych do wykonywania operacji na liczbach rzeczywistych, gdy przetwarzane są tylko dane tego typu (np. : realpow, realsqrt, reallog), • odpowiednia konstrukcja wyrażeń warunkowych w instrukcjach: if i while - gdy używane są w nich operatory && oraz || nie zawsze zachodzi potrzeba obliczania wartości całego wyrażenia, • unikanie przeciążania wbudowanych funkcji Matlaba, • stosowanie m-plików funkcyjnych zamiast skryptowych, • stosowanie, o ile to możliwe, funkcji load i save zamiast fread i fwrite.
- Slides: 16