Instabile Timings der C ++/CUDA -Funktion, je nachdem, wie es von Python aufgerufen wirdPython

Python-Programme
Anonymous
 Instabile Timings der C ++/CUDA -Funktion, je nachdem, wie es von Python aufgerufen wird

Post by Anonymous »

Ich habe eine C ++-Bibliothek, die sich auf CUDA stützt, um einen Matrix-Vektor-Betrieb auf der GPU durchzuführen, auf dem ich einen Python-Wrapper mit Pybind11 erstellt habe. Ich definiere schließlich ein reines Python-Modul, das dieses von Pybind11 hergestellte Modul importiert und eine Klasse definiert, die von scipy.sparse.LINALG.LINEAROPERATOR erbt. Der Konstruktor dieser Klasse ruft den Konstruktor meiner zugrunde liegenden C ++ -Klasse und eine _matvec -Methode ein, die die CUDA-CUDA-CUSC-Operation vorsieht. />
Wenn ich einige Zeit in Folge zum Matvec -Vorgang rufe, zeigt sein Timing einen starken CUDA -Aufwärmeffekt: Der erste Anruf braucht viel Zeit, aber die nachfolgenden sind viel schneller. Der Code würde so aussehen wie: < /li>
< /ul>

Code: Select all

for _ in range(N_matvec):
res = custom_operator @ x
< /code>
Beispiel Timing -Ergebnisse sind: < /p>
[Timing] 24.7192ms
[Timing] 1.80133ms
[Timing] 1.56456ms
[Timing] 1.55432ms
< /code>

 Wenn ich jedoch scipy iterative lineare Löser dafür verwende (die unter der Haube denselben Matvec < /code> bei jeder Iteration des Lösers aufruft): < /li>
< /ul>
 < /ul>x,info = gmres(custom_operator, b)
< /code>
Jede Matvec-Operation braucht viel Zeit (nein "Warm-up" beobachtet) < /p>
[Timing] 22.673ms
[Timing] 13.2894ms
[Timing] 14.2284ms
[Timing] 33.5462ms
Als ob der Cuda -Kontext zwischen den verschiedenen Aufrufen verloren ging. Ausführung meines Codes mit NSIGHT. Die Idee, was ich tue, ist wie folgt: < /p>

Code: Select all

# First call to "warm-up"
res = custom_operator @ x
# Then subsequent calls to the operation to time it
for _ in range(10):
res = custom_operator @ x
# Finally solving a linear system using scipy's GMRES
x,info = gmres(custom_operator, b)
parallel zur NSIGHT -Profilierung habe ich auch diesen MATVEC -Funktionsaufruf von seinem C ++ - Code mit Cime fest. Nichts als Cuda -Aufrufe finden im zeitgesteuerten Teil des Codes statt. Verschiedene Aufrufe dieser Matvec -Funktion. Hier ist der Farbcode: < /p>

In rot: seine erste Ausführung < /li>
In Blau: Die 10 Anrufe im Zusammenhang mit dem Timing < /li>
In Green: Die ersten (von vielen), die mit dem SCIPY -Gmres -Löwen -Drucken -Drucken -Drucken -Drucken (von Scipy "-Don -zu -my /li> < /< /> < /ol> < /ol> < /ol> < /ol> < /ol> < /ol> < /ol> < /< /ol> < /< /> < /> < /< /> < /< /> < /< /> < /< /> < /> < /> < /> < /> < /> < /< /> < /< /

[Timing] 112.922ms​ // 1st "warmup" call
// Bellow = 10 calls used to time it
[Timing] 1.81147ms​
[Timing] 1.65732ms​
[Timing] 1.77153ms​
[Timing] 1.59583ms​
[Timing] 1.60697ms​
[Timing] 1.6098ms​
[Timing] 4.09182ms​
[Timing] 1.60247ms​
[Timing] 1.59104ms​
[Timing] 1.60287ms​
// Bellow = first 7 calls part of GMRES solving
[Timing] 11.0192ms​
[Timing] 23.8186ms​
[Timing] 29.4516ms​
[Timing] 44.2932ms​
[Timing] 44.6093ms​
[Timing] 48.826ms​
[Timing] 41.7389ms
< /code>
Ich beobachte, dass: < /p>

Für meine ersten 11 Anrufe (Warm-up-Anruf+ 10 Aufrufe, die zur Zeit verwendet werden) Die Zeit, die ich von meinem C ++-Timing mit dem Timing von "C ++" -Timing erhalte. LOLVER Ich beobachte immer noch die gleiche Zeit aus dem NSIGHT (Spannweite der Cuda -API -Anrufe ~ 1,8 ms), aber ich bekomme in meinen Timing -Protokollen etwas viel größeres (zwischen 11 ms und 49 ms in den wenigen Aufrufen als Beispiel). Bezogen auf? Zeitleiste eines MatVec -Vorgangs von Scipy's Solver:

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post