Brendan Greggs CPU-Flammendiagramme sind eine Möglichkeit, die CPU-Auslastung über einen bestimmten Zeitraum basierend auf Aufruflisten zu visualisieren.
Seine FlameGraph-Github-Projekt bietet eine sprachunabhängige Möglichkeit, diese Diagramme zu zeichnen:
Für jede Sprache benötigt FlameGraph eine Möglichkeit, Stapeleingaben in Form von Zeilen wie dieser bereitzustellen:
grandparent_func;parent_func;func 42
Dies bedeutet, dass das instrumentierte Programm als laufende Funktion beobachtet wurde funcwoher das aufgerufen wurde parent_funcdie wiederum von der Funktion der obersten Ebene aufgerufen wird grandparent_func. Es heißt, dass der Aufrufstapel 42 Mal beobachtet wurde.
Wie kann ich Stack-Informationen aus Python-Programmen sammeln und sie FlameGraph zur Verfügung stellen?
Für Bonuspunkte: Wie kann das so erweitert werden, dass sowohl der C- als auch der Python-Stack angezeigt werden, oder sogar bis zum Kernel unter Linux (ähnlich wie bei einigen Flammendiagrammen für Java und node.js auf Brendans Website)?
Sie sollten in der Lage sein, etwas mit dtrace zu tun – erfordert ein Betriebssystem, das dtrace und eine gepatchte Version von Python unterstützt.
– ErikR
17. Januar 2015 um 15:36 Uhr
Für das, was es wert ist, übersteigt meiner Meinung nach die Schönheit von Flammendiagrammen ihre Nützlichkeit zum Auffinden von Beschleunigungen, und es gibt einen Weg, der weniger hübsch, aber effektiver ist. Hier erklärt.
– Mike Dunlavey
18. Januar 2015 um 1:29 Uhr
user5402: Zuletzt habe ich gehört, dass dtrace nicht für den Produktionseinsatz unter Linux geeignet ist
– Croad Langshan
18. Januar 2015 um 17:15 Uhr
Mike Dunlavey: Ich bin nicht anderer Meinung, aber ich denke, es ist alles in Ordnung, Leistungsprobleme zu finden, also würde ich auch gerne Flammendiagramme ausprobieren
– Croad Langshan
18. Januar 2015 um 17:17 Uhr
Perf-Skript [-s [Python]:Skript[.py] ], aber der Linux-Kernel sollte mit einem speziellen Flag (NO_LIBPYTHON=0) wie hier beschrieben gebaut werden askubuntu.com/questions/577768/…
– VelikiiNehochuha
2. Mai 2016 um 22:12 Uhr
gdlmx
Vielleicht kannst du es versuchen sys.setprofiledas ist der Kern für den Standard-Python-Profiler profile und cProfile. Diese Methode setzt einen Haken zu den “call”- und “return”-Ereignissen jeder Funktion, einschließlich jener Funktionen der C-API.
Die Profilfunktion des Systems wird ähnlich wie die Trace-Funktion des Systems aufgerufen (siehe settrace()), aber sie wird nicht für jede ausgeführte Codezeile aufgerufen (nur bei Aufruf und Rückgabe, aber das Rückgabeereignis wird auch dann gemeldet, wenn eine Ausnahme aufgetreten ist einstellen).
Unten ist ein funktionierendes Beispiel:
from time import clock
t0 = clock()
def getFun(frame):
code = frame.f_code
return code.co_name+' in '+code.co_filename+':'+str(code.co_firstlineno)
def trace_dispatch(frame, event, arg):
if event in [ "c_call" , 'call', 'return', 'c_return']:
t = int((clock()-t0)*1000)
f = frame
stack=[]
while(f):
stack.insert( 0,getFun(f) )
f = f.f_back
print event, '\t', '; '.join(stack), '; ', t
import sys
sys.setprofile(trace_dispatch)
try:
execfile('test.py')
finally:
sys.setprofile(None)
c_call 0
call <module> in test.py:2 ; 1
call <module> in test.py:2; main in test.py:5 ; 1
call <module> in test.py:2; main in test.py:5; f in test.py:2 ; 5
return <module> in test.py:2; main in test.py:5; f in test.py:2 ; 8
return <module> in test.py:2; main in test.py:5 ; 11
return <module> in test.py:2 ; 14
c_return 18
c_call 21
Sehen Sie sich eine umfassendere Profilerstellungsfunktion an hier.
C-Stapel in Python
Sie können innerhalb des Python-Interpreters nicht auf den C-Stack zugreifen. Es ist erforderlich, einen Debugger oder Profiler zu verwenden, der C/C++ unterstützt. Ich würde empfehlen gdb-python.
Vielen Dank für all diese Informationen – das ist hilfreich
– slashdottir
4. Mai 2016 um 22:59 Uhr
Das ist großartig, aber ich denke, das tut es nicht ziemlich Beantworten Sie die Frage aus dem trivialen, aber wichtigen Grund, dass sie meiner Meinung nach keine Ausgabe in der Form erzeugt, die FlameGraph möchte
– Croad Langshan
8. Juni 2016 um 22:37 Uhr
@gdlmx Richtig. Ich auch nicht
– Croad Langshan
14. Juni 2016 um 20:46 Uhr
Pyflame unterstützt das Zeichnen von Flammendiagrammen in zwei Formaten (entweder die ‘traditionelle’ Form wie in der Frage oder die ‘seitlichen’ Flammendiagramme von Chrome unter Verwendung von Chrom selbst).
# Attach to PID 12345 and profile it for 1 second
pyflame -p 12345
# Attach to PID 768 and profile it for 5 seconds, sampling every 0.01 seconds
pyflame -s 5 -r 0.01 -p 768
# Run py.test against tests/, emitting sample data to prof.txt
pyflame -o prof.txt -t py.test tests/
13702000cookie-checkCPU-Flammendiagramme für Pythonyes
Sie sollten in der Lage sein, etwas mit dtrace zu tun – erfordert ein Betriebssystem, das dtrace und eine gepatchte Version von Python unterstützt.
– ErikR
17. Januar 2015 um 15:36 Uhr
Für das, was es wert ist, übersteigt meiner Meinung nach die Schönheit von Flammendiagrammen ihre Nützlichkeit zum Auffinden von Beschleunigungen, und es gibt einen Weg, der weniger hübsch, aber effektiver ist. Hier erklärt.
– Mike Dunlavey
18. Januar 2015 um 1:29 Uhr
user5402: Zuletzt habe ich gehört, dass dtrace nicht für den Produktionseinsatz unter Linux geeignet ist
– Croad Langshan
18. Januar 2015 um 17:15 Uhr
Mike Dunlavey: Ich bin nicht anderer Meinung, aber ich denke, es ist alles in Ordnung, Leistungsprobleme zu finden, also würde ich auch gerne Flammendiagramme ausprobieren
– Croad Langshan
18. Januar 2015 um 17:17 Uhr
Perf-Skript [-s [Python]:Skript[.py] ], aber der Linux-Kernel sollte mit einem speziellen Flag (NO_LIBPYTHON=0) wie hier beschrieben gebaut werden askubuntu.com/questions/577768/…
– VelikiiNehochuha
2. Mai 2016 um 22:12 Uhr