Abstand zwischen den Segmenten mit numba jit, Python

8

Ich habe in der letzten Woche verwandte Fragen zu diesem Stapel gestellt, um zu versuchen, Dinge zu isolieren, die ich nicht verstand, den @jit-Dekorator mit Numba in Python zu verwenden. Ich stoße jedoch gegen die Wand, also schreibe ich einfach das ganze Problem.

Das Problem besteht darin, den minimalen Abstand zwischen Paaren einer großen Anzahl von Segmenten zu berechnen. Die Segmente werden durch ihre Anfangs- und Endpunkte in 3D dargestellt. Mathematisch wird jedes Segment als [AB] = A + (B - A) * s parametrisiert, wobei s in [0,1] und A und B der Anfangs- und Endpunkt des Segments sind. Für zwei solcher Segmente kann der minimale Abstand berechnet werden und die Formel wird hier angegeben.

Ich habe dieses Problem bereits auf einem anderen thread , und die gegebene Antwort befasste sich mit dem Ersetzen von doppelten Schleifen meines Codes durch Vektorisieren des Problems, was jedoch Speicherprobleme für große Mengen von Segmenten treffen würde. Daher habe ich beschlossen, bei den Loops zu bleiben und stattdessen von numba zu verwenden.

Da die Lösung des Problems viele Punktprodukte erfordert, wird numpys Punktprodukt nicht von numba unterstützt Ich begann mit der Umsetzung meines eigenen 3D-Dot-Produkts.

%Vor%

Die Funktion, die den minimalen Abstand aller Paare in N Segmenten berechnet, nimmt als Eingabe ein Nx6 Array (6 Koordinaten)

%Vor%

Also nimmt compute_stuff (arg) als Argument ein 2D np.array (double [:,:]), führt eine Reihe von numba-unterstützten (?) Operationen aus und gibt ein weiteres 2D np.array (double [:, :]). Jedoch,

%Vor%

Ich bekomme 134 und 123 ms pro Schleife. Können Sie etwas darüber sagen, warum ich meine Funktion nicht beschleunigen kann? Jede Rückmeldung würde sehr geschätzt werden.

    
Mathusalem 10.03.2015, 18:01
quelle

1 Antwort

9

Hier ist meine Version Ihres Codes, die wesentlich schneller ist:

%Vor%

Und die Zeiten:

%Vor%

Meine grundlegende Strategie für die Beschleunigung war:

  • Entfernen Sie alle Array-Ausdrücke und rollen Sie die Vektorisierung explizit ab (besonders, weil Ihre Arrays so klein sind)
  • Entfernen Sie in Ihren Aufrufen der Methode dot redundante Berechnungen (indem Sie zwei Vektoren subtrahieren).
  • Verschieben Sie alle Array-Erstellungen nach außerhalb der verschachtelten for-Schleifen, damit numba möglicherweise einige Schleifen heben . Dies vermeidet auch die Erzeugung vieler kleiner Arrays, was teuer ist. Es ist besser, einmal zu reservieren und den Speicher wiederzuverwenden.

Eine andere Sache, die man beachten sollte, ist, dass für neuere Versionen von numba, was man autojit nennt (dh luing numba gibt Rückschlüsse auf die Eingaben) und jetzt nur der Dekorator ohne Typhinweise ist, genauso schnell wie das Spezifizieren Ihre Eingabe Typen in meiner Erfahrung.

Auch Timings wurden mit numba 0.17.0 auf OS X unter Verwendung der Anaconda-Python-Distribution mit Python 2.7.9 ausgeführt.

    
JoshAdel 11.03.2015, 01:47
quelle

Tags und Links