2016-07-24 34 views
7

Pobiegłem julia --track-allocation prof.jl powodując następujący wynik:Optymalizacja dala resztkowego alokację sterty w Julia

- using FixedSizeArrays 
    - 
    - immutable KernelVals{T} 
    -  wavenumber::T 
    -  vect::Vec{3,T} 
    -  dist::T 
    -  green::Complex{T} 
    -  gradgreen::Vec{3,Complex{T}} 
    - end 
    - 
    - function kernelvals(k, x, y) 
    -  r = x - y 
    0  R2 = r[1]*r[1] 
    0  R2 += r[2]*r[2] 
    0  R2 += r[3]*r[3] 
    0  R = sqrt(R2) 
    - 
    0  γ = im*k 
    0  expn = exp(-γ * R) 
    0  fctr = 1.0/(4.0*pi*R) 
    0  green = fctr * expn 
    64  gradgreen = -(γ + 1/R) * green/R * r 
    - 
    0  KernelVals(k, r, R, green, gradgreen) 
    - end 
    - 
    - function payload() 
    - x = Vec{3,Float64}(0.47046262275611883,0.8745228524771103,-0.049820876498487966) 
    0 y = Vec{3,Float64}(-0.08977259509004082,0.543199687600189,0.8291184043296924) 
    0 k = 1.0 
    0 kv = kernelvals(k,x,y) 
    - return kv 
    - end 
    - 
    - function driver() 
    - println("Flush result: ", payload()) 
    0 Profile.clear_malloc_data() 
    0 payload() 
    - end 
    - 
    - driver() 

nie mogę pozbyć się ostatecznej alokacji pamięci na linii startu gradgreen.... Uruchomiłem @code_warntype kernelsvals(...), ujawniając niestabilność lub niepewność tego typu.

Wzór alokacji jest identyczny na julia-0.4.6 i julia-0.5.0-pre.

Ta funkcja będzie wewnętrznym jądrem w implementowanej przeze mnie metodzie elementu brzegowego. Będzie się to nazywać miliony razy, co spowoduje dużą alokację pamięci, która może stać się wielokrotnością fizycznej pamięci dostępnej dla mnie.

Powodem, dla którego używam FixedSizeArrays jest uniknięcie przydziałów związanych z tworzeniem małych Array s.

Dokładna lokalizacja, w której zgłasza się przydział, zależy w bardzo delikatny sposób od kodu. W pewnym momencie program do profilowania pamięci obwiniał 1/(4*pi*R) jako alokację wyzwalania linii.

Każda pomoc lub ogólne wskazówki dotyczące pisania kodu, powodujące przewidywalne wzorce alokacji, są wysoko cenione.

Odpowiedz

3

Po kilku eksperymentach udało mi się wreszcie pozbyć wszystkich przydziałów. Sprawcą okazała się architektura promocji rozszerzona w FixedSizeArrays. Wygląda na to, że pomnożenie złożonego skalaru i rzeczywistego wektora tworzy tymczasowy po drodze.

Wymiana definicję gradgreen z

c = -(γ + 1/R) * green/R 
gradgreen = Vec(c*r[1], c*r[2], c*r[3]) 

wyników w seriach alokacji wolne. W moim przykładzie porównawczym czas wykonania spadł z 6,5 sekundy do 4,15 sekundy. Łączny rozmiar alokacji od 4,5 GB do 1,4 GB.

EDT: Zgłoszono ten problem deweloperom FixedSizeArrays, którzy natychmiast je naprawili (dziękuję!). Alokacje zniknęły całkowicie.

+0

Niezła praca nad tym, aby to zrozumieć, opracować indywidualne rozwiązanie, a następnie dokonać globalizacji! –