2016-07-24 46 views
7

Ich lief julia --track-allocation prof.jl in der folgenden Ausgabe führt:Optimierung weg Rest Heapzuordnung in 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() 

Ich kann nicht die letzten Speicherzuweisung auf der Linie loszuwerden gradgreen... starten. Ich lief @code_warntype kernelsvals(...) und ergab keine Art Instabilität oder Unsicherheit.

Das Zuweisungsmuster ist identisch mit julia-0.4.6 und julia-0.5.0-pre.

Diese Funktion ist der innere Kernel in einer Boundary-Element-Methode, die ich implementiere. Es wird buchstäblich millionenfach aufgerufen, was zu einer groben Speicherzuweisung führt, die ein Vielfaches des verfügbaren physikalischen Speichers für mich sein kann.

Der Grund, warum ich FixedSizeArrays verwende, ist die Vermeidung von Zuweisungen im Zusammenhang mit der Erstellung von kleinen Array s.

Der genaue Ort, an dem die Zuweisung gemeldet wird, hängt sehr empfindlich vom Code ab. Irgendwann beschuldigte der Speicherprofiler 1/(4*pi*R) als die Leitung, die die Zuweisung auslöst.

Jede Hilfe oder allgemeine Tipps zum Schreiben von Code, die zu vorhersagbaren Zuweisungsmustern führen, wird sehr geschätzt.

Antwort

3

Nach einigen Experimenten habe ich es schließlich geschafft, alle Zuweisungen zu entfernen. Der Täter stellte sich als die in FixedSizeArrays erweiterte Promotion-Architektur heraus. Das Multiplizieren eines komplexen Skalars mit einem realen Vektor erzeugt auf dem Weg eine temporäre.

Ersetzen der Definition von gradgreen mit

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

Ergebnisse bei der Zuweisung frei läuft. In meinem Benchmark-Beispiel fiel die Ausführungszeit von 6,5 Sekunden auf 4,15 Sekunden. Gesamtgröße der Zuweisung von 4,5 GB bis 1,4 GB.

EDT: Dieses Problem gemeldet an FixedSizeArrays Entwickler, die es sofort behoben (danke!). Zuteilungen sind vollständig verschwunden.

+0

Schöne Arbeit am Detektiv, um das herauszufinden, eine individuelle Lösung zu entwickeln, und dann globalisieren! –