これは、多くのプロファイラーからの出力をドット グラフに変換する Python スクリプトです。
できる:
gprof2dotによって生成されたグラフの対話型ビューアが必要な場合は、xdot.py を確認してください。
現在、 gprof2dot は私のニーズを満たしていますが、メンテナンスに費やす時間がほとんど、またはまったくありません。そのため、リクエストされた機能が実装される可能性は低く、問題レポートやプル リクエストの処理が遅くなる可能性があるのではないかと心配しています。
これは、デフォルト設定での Linux Gazette 記事のサンプル データの結果です。
Debian/Ubuntu では次を実行します。
apt-get install python3 graphviz
RedHat/Fedora 実行時
yum install python3 graphviz
PyPI
pip install gprof2dot
スタンドアロンスクリプト
Gitリポジトリ
Usage:
gprof2dot.py [options] [file] ...
Options:
-h, --help show this help message and exit
-o FILE, --output=FILE
output filename [stdout]
-n PERCENTAGE, --node-thres=PERCENTAGE
eliminate nodes below this threshold [default: 0.5]
-e PERCENTAGE, --edge-thres=PERCENTAGE
eliminate edges below this threshold [default: 0.1]
-f FORMAT, --format=FORMAT
profile format: axe, callgrind, collapse, dtrace,
hprof, json, oprofile, perf, prof, pstats, sleepy,
sysprof or xperf [default: prof]
--total=TOTALMETHOD preferred method of calculating total time: callratios
or callstacks (currently affects only perf format)
[default: callratios]
-c THEME, --colormap=THEME
color map: bw, color, gray, pink or print [default:
color]
-s, --strip strip function parameters, template parameters, and
const modifiers from demangled C++ function names
--color-nodes-by-selftime
color nodes by self time, rather than by total time
(sum of self and descendants)
-w, --wrap wrap function names
--show-samples show function samples
--node-label=MEASURE measurements to on show the node (can be specified
multiple times): self-time, self-time-percentage,
total-time or total-time-percentage [default: total-
time-percentage, self-time-percentage]
--list-functions=LIST_FUNCTIONS
list functions available for selection in -z or -l,
requires selector argument ( use '+' to select all).
Recall that the selector argument is used with
Unix/Bash globbing/pattern matching, and that entries
are formatted '::'. When
argument starts with '%', a dump of all available
information is performed for selected entries, after
removal of leading '%'.
-z ROOT, --root=ROOT prune call graph to show only descendants of specified
root function
-l LEAF, --leaf=LEAF prune call graph to show only ancestors of specified
leaf function
--depth=DEPTH prune call graph to show only descendants or ancestors
until specified depth
--skew=THEME_SKEW skew the colorization curve. Values < 1.0 give more
variety to lower percentages. Values > 1.0 give less
variety to lower percentages
-p FILTER_PATHS, --path=FILTER_PATHS
Filter all modules not in a specified path
--compare Compare two graphs with almost identical structure. With this
option two files should be provided.gprof2dot.py
[options] --compare [file1] [file2] ...
--compare-tolerance=TOLERANCE
Tolerance threshold for node difference
(default=0.001%).If the difference is below this value
the nodes are considered identical.
--compare-only-slower
Display comparison only for function which are slower
in second graph.
--compare-only-faster
Display comparison only for function which are faster
in second graph.
--compare-color-by-difference
Color nodes based on the value of the difference.
Nodes with the largest differences represent the hot
spots.
perf record -g -- /path/to/your/executable
perf script | c++filt | gprof2dot.py -f perf | dot -Tpng -o output.png
opcontrol --callgraph=16
opcontrol --start
/path/to/your/executable arg1 arg2
opcontrol --stop
opcontrol --dump
opreport -cgf | gprof2dot.py -f oprofile | dot -Tpng -o output.png
xperf に詳しくない場合は、まずこの優れた記事を読んでください。次に、次のようにします。
xperf を次のように起動します
xperf -on Latency -stackwalk profile
アプリケーションを実行します。
データを保存します。 ` xperf -d 出力.etl
ビジュアライザーを開始します。
xperf output.etl
[トレース]メニューで、 [シンボルの読み込み]を選択します。必要に応じてシンボル パスを設定します。
CPU サンプリング グラフで関心のある領域を選択し、右クリックして[サマリー テーブル]を選択します。
[列]メニューで、 [スタック]列が有効になっていて表示されていることを確認します。
行を右クリックし、 「Export Full Table」を選択し、 「output.csv」に保存します。
次に、 gprof2dot を次のように呼び出します
gprof2dot.py -f xperf output.csv | dot -Tpng -o output.png
次のようにプロファイル データを収集します (GUI からも実行できます)。
amplxe-cl -collect hotspots -result-dir output -- your-app
プロファイル データを次のように視覚化します。
amplxe-cl -report gprof-cc -result-dir output -format text -report-output output.txt
gprof2dot.py -f axe output.txt | dot -Tpng -o output.png
Kirill Rogozhin のブログ投稿も参照してください。
/path/to/your/executable arg1 arg2
gprof path/to/your/executable | gprof2dot.py | dot -Tpng -o output.png
python -m profile -o output.pstats path/to/your/script arg1 arg2
gprof2dot.py -f pstats output.pstats | dot -Tpng -o output.png
python -m cProfile -o output.pstats path/to/your/script arg1 arg2
gprof2dot.py -f pstats output.pstats | dot -Tpng -o output.png
java -agentlib:hprof=cpu=samples ...
gprof2dot.py -f hprof java.hprof.txt | dot -Tpng -o output.png
詳細については、Russell Power のブログ投稿を参照してください。
dtrace -x ustackframes=100 -n 'profile-97 /pid == 12345/ { @[ustack()] = count(); } tick-60s { exit(0); }' -o out.user_stacks
gprof2dot.py -f dtrace out.user_stacks | dot -Tpng -o output.png
# Notice: sometimes, the dtrace outputs format may be latin-1, and gprof2dot will fail to parse it.
# To solve this problem, you should use iconv to convert to UTF-8 explicitly.
# TODO: add an encoding flag to tell gprof2dot how to decode the profile file.
iconv -f ISO-8859-1 -t UTF-8 out.user_stacks | gprof2dot.py -f dtrace
Brendan Gregg の FlameGraph ツールは、サンプルごとに 1 行を含むテキスト ファイルを入力として受け取ります。この形式は、FlameGraph リポジトリのstackcollapse
スクリプトを使用して、他のさまざまな入力から生成できます。 py-spy などのツールによって生成することもできます。
使用例:
パフォーマンス
perf record -g -- /path/to/your/executable
perf script | FlameGraph/stackcollapse-perf.pl > out.collapse
gprof2dot.py -f collapse out.collapse | dot -Tpng -o output.png
スパイ、スパイ
py-spy record -p -f raw -o out.collapse
gprof2dot.py -f collapse out.collapse | dot -Tpng -o output.png
この画像は、 --compare
および--compare-color-by-difference
オプションの使用例を示しています。
右向きの矢印は、2 番目のプロファイル (2 番目のプロファイル) で関数の実行が速かったノードを示し、左向きの矢印は、最初のプロファイル (1 番目のプロファイル) で関数の実行が速かったノードを示します。 。
+-----------------------------+
| function name
| total time % -/+ total_diff
| ( self time % ) -/+ self_diff /
| total calls1 / total calls2 /
+-----------------------------+
どこ
total time %
とself time %
最初のプロファイルから取得されますdiff
はtime in the first profile - time in the second profile
の絶対値として計算されます。注比較オプションは、pstats、ax、および callgrind プロファイルに対してテストされています。
出力グラフのノードは関数を表し、次のレイアウトになります。
+------------------------------+
| function name |
| total time % ( self time % ) |
| total calls |
+------------------------------+
どこ:
エッジは 2 つの関数間の呼び出しを表し、次のレイアウトを持ちます。
total time %
calls
parent --------------------> children
どこ:
再帰サイクルでは、ノード内の合計時間% はサイクル内の関数全体で同じであり、サイクル内のエッジに% 合計時間の数値は存在しないことに注意してください。そのような数値は意味をなさないからです。
ノードとエッジの色は、合計時間の %値に応じて変化します。デフォルトの温度に似たカラーマップでは、ほとんどの時間が費やされる関数 (ホットスポット) は飽和した赤でマークされ、ほとんど時間が費やされない関数は濃い青でマークされます。時間がほとんどかからない関数、またはまったく時間がかかっていない関数は、デフォルトではグラフに表示されないことに注意してください。
--list-functions
フラグを使用すると、 gprof
入力で見つかった関数エントリのリストを許可します。これは、 --leaf
( -l
) または--root
( -z
) フラグを使用した使用を準備するツールとして意図されています。
prof2dot.py -f pstats /tmp/myLog.profile --list-functions "test_segments:*:*"
test_segments:5:,
test_segments:206:TestSegments,
test_segments:46:
selector 引数は、 -l
および-z
フラグで実行されるのと同じ方法で、Unix/Bash のグロビング/パターン マッチングで使用されます。
エントリの形式は「
セレクター引数が '%' で始まる場合、セレクターの先頭の '%' が削除された後、選択されたエントリに対して利用可能なすべての情報のダンプが実行されます。セレクターが「+」または「*」の場合、関数の完全なリストが出力されます。
デフォルトでは、 gprof2dot.py
部分的なコール グラフを生成し、合計計算時間にほとんどまたはまったく影響を与えないノードとエッジを除外します。完全なコール グラフが必要な場合は、次のように-n
/ --node-thres
および-e
/ --edge-thres
オプションを使用してノードとエッジのゼロしきい値を設定します。
gprof2dot.py -n0 -e0
C++ コードをプロファイリングする場合、分解された C++ 関数名にスコープ、関数引数、およびテンプレート引数が含まれるため、ノード ラベルの幅が非常に広くなる可能性があります。
関数とテンプレートの引数情報が必要ない場合は、 -s
/ --strip
オプションを渡してそれらを削除します。
すべての情報を保持したい場合、またはラベルの幅がまだ広すぎる場合は、 -w
/ --wrap
渡してラベルを折り返すことができます。 dot
ラベルを自動的に折り返さないため、ラベルの余白は完全に揃えられないことに注意してください。
おそらく、合計実行時間が短すぎるため、時間がどこに費やされているかを判断するためのプロファイルの精度が十分ではありません。
次のように-n
/ --node-thres
および-e
/ --edge-thres
オプションを使用してノードとエッジにゼロしきい値を設定することで、グラフ全体を強制的に表示することもできます。
gprof2dot.py -n0 -e0
ただし、意味のある結果を得るには、プログラムを長期間実行する方法 (複数の実行からの結果を集計する) を見つける必要があります。
実行時間が短すぎるため、丸め誤差が大きくなる可能性があります。
実行時間を増やす方法については、上記の質問を参照してください。
適切な結果を生み出すために不可欠なオプションは次のとおりです。
-g
: デバッグ情報を生成します-fno-omit-frame-pointer
: フレーム ポインターを使用します (x86_64 などの一部のアーキテクチャおよび一部の最適化レベルでは、フレーム ポインターの使用はデフォルトで無効になっています。これなしでコール スタックをウォークスルーすることは不可能です) gprof を使用している場合は、 -pg
オプションも必要になりますが、最近では他のプロファイリング ツールを使用するとはるかに優れた結果が得られ、そのほとんどはコンパイル時に特別なコード計測を必要としません。
プロファイリングしているコードは、リリースするコードにできるだけ近づけたいと考えています。したがって、リリース コードに使用するすべてのオプションを含める必要があります。通常は次のとおりです。
-O2
: 空間速度のトレードオフを考慮しない最適化-DNDEBUG
: 標準ライブラリのデバッグ コード (assert マクロなど) を無効にします。ただし、gcc によって実行される最適化の多くは、プロファイリング結果の精度/粒度に干渉します。特定の最適化を無効にするには、次のオプションを渡す必要があります。
-fno-inline-functions
: 関数を親にインライン化しません (そうしないと、これらの関数に費やされた時間は呼び出し元に帰属します)-fno-inline-functions-called-once
: 上記と同様-fno-optimize-sibling-calls
: 兄弟呼び出しと末尾の再帰呼び出しを最適化しません (そうしないと、末尾の呼び出しが親関数に起因する可能性があります)それでも粒度が低すぎる場合は、次のオプションを渡して、より細かい粒度を実現できます。
-fno-default-inline
: メンバー関数がクラス スコープ内で定義されているという理由だけで、デフォルトでインライン化されません。-fno-inline
: inline キーワードには注意を払いません。ただし、これらの最後のオプションを使用すると、関数呼び出しのオーバーヘッドにより、関数が何度も呼び出されるタイミングが歪むことに注意してください。これは、適切なパフォーマンスを得るためにこれらの最適化が行われることが期待される一般的な C++ コードに特に当てはまります。詳細については、gcc 最適化オプションの完全なリストを参照してください。
補完/代替ツールを含む外部リソースについては、Wiki を参照してください。