160 likes | 310 Views
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.
E N D
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 = example1(Count) • for k = 1:Count • result(k) = sin(k/50); • if result(k) < -0.9 • result(k) = gammaln(k); • end • 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 function result = example1(Count) result = zeros(1, Count); for k = 1:Count result(k) = sin(k/50);% 0.002s if result(k) < -0.9 result(k) = gammaln(k); end end • rezerwacja pamięci na tablicę o znanych wymiarach • odpowiedni dobór typu liczb – operacja na liczbach całkowitych są wykonywane szybciej niż na liczbach rzeczywistych
1. function y = modfun1(x) y = 1.2*x; 2. function x = modfun2(x) x = 1.2*x; • unikanie tworzenia niepotrzebnych zmiennych • Czas wykonania dla tablicy o wymiarach 3000 x 3000: • 2.731s • 0.219s • zachowanie typów zmiennych
1. y = zeros(N); for r = 1:N for c = 1:N if x(r,c) > 0 y(r,c) = x(r,c); end end end 2. y = zeros(N); for c = 1:N for r = 1:N if x(r,c) > 0 y(r,c) = x(r,c); end end end • przetwarzanie elementów tablic po kolumnach • Czas wykonania przy N = 3000 i4497523 elementach nieujemnych • 3.11s • 0.755s
Jeśli algorytm na to pozwala – traktować tablicę jako wektor i stosować indeksowanie liniowe y = zeros(N); for k = 1:N*N if x(k) > 0 y(k) = x(k); end end Czas wykonania: 0.672s.
Stosowanie konstrukcji, których działanie przyspiesza JIT-Accelerator • Od wersji 6.5 Matlab zawiera tzw. JIT-Accelerator, który znacznie skraca • czas wykonywania pętli. Należy jednak przestrzegać kilku zasad: • zmienne muszą być typu: double, complex, logical, char,int8, uint8, int16, uint16, int32, uint32; nie są przyspieszane operacje na: komórkach, strukturach, tablicach rzadkich oraz z użyciem uchwytów do funkcji, • tablice mogą mieć co najwyżej trzy wymiary, • nie może następować zmiana rozmiaru ani typu zmiennej, • używane funkcje mogą być tylko funkcjami wbudowanymi Matlaba, • wynik wyrażenia w instrukcjach: if, switch i while musi być skalarem, • zmienna sterująca pętli for musi przyjmować wartości skalarne, • 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 • wierszyi 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.01 1. k = 0; for t = 0:.01:100 k = k + 1; y(k) = cos(t); end 2. y = cos(0:.01:100); • Czas wykonania: • 0.209s bez rezerwacji pamięci na tablicę wyników, 0.115s z rezerwacją • 0.024s
Utworzenie tablicy y z elementów tablicy x, przy czym elementy nieujemne mają pozostać, pozostałe mają być zastąpione 0 1. y = zeros(N); for c = 1:N for r = 1:N if x(r,c) > 0 y(r,c) = x(r,c); end end end 2. y = zeros(N); t = x > 0; y(t) = x(t); • Czas wykonania (warunki pomiaru jak wcześniej): • 0.755s • 0.823s
Obliczenie sumy ciągu: 1 + 1/2 + 1/3 + ... + 1/n 1. suma = 0; for k = 1:n suma = suma + 1/k; end 2. suma = sum(1./(1:n)); • Czas wykonania przy n = 100000: • 0.001s • 0.006s
Obliczenie sumy elementów leżących na przekątnej głównej tablicy 1. m = size(A,1); suma = 0; for k = 1:m suma = suma + A(k,k); end 2. suma = sum(diag(A)); • Czas wykonania przy tablicy A o wymiarach 1000 x 1000: • 0.00013s • 0.00028s
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.