straceprof——とにかく簡単にビルドのプロファイルを取るためのソフトウェア
三行まとめ
- straceprof は
strace
コマンドを利用して Linux 上のマルチプロセスで動くプログラムをプロファイルするためのソフトウェアです。 - straceprof は
strace
コマンドが使えるところならどこでも使うことができます。 - straceprof はソフトウェアのビルドのプロファイルを特に念頭に置いて書かれています。
とりあえず使ってみたい人向けのコマンド
$ sudo apt-get install strace
$ pip install straceprof
$ strace \
--trace=execve,execveat,exit,exit_group \
--follow-forks \
--string-limit=1000 \
--absolute-timestamps=format:unix,precision:us \
--output=straceprof.log \
<command to profile>
$ straceprof \
--log=straceprof.log \
--output=straceprof.png
ソフトウェアのビルドのプロファイル
仕事でもプライベートでも少し規模の大きいソフトウェアをビルドする機会がかなりの頻度であります。 例えば、ビルドしているのは、Linux カーネルや Julia、PyTorch、glibc といったソフトウェアです。 これらのソフトウェアは僕のPC1でフルビルドに5分から30分程度かかります。 差分ビルドであってもフルビルドほどではないにせよそれなりの時間がかかります。
このビルド時間は少し変更を入れて動作確認するたびにかかるので、作業効率を上げるためにはこれを縮めることが大変重要です。 ビルド時間を短縮するというのは一種のパフォーマンスチューニングです。 このため、ビルドプロセス全体のプロファイルがとり、ボトルネックを特定する必要があります。
ここで、ビルドプロセスのプロファイルをとるのが難しい場合が多い、という問題があります。
ソフトウェアのビルドに使われているツールは多様で、しかもそれらがシェルスクリプトや Dockerfile などで組み合わされていることがあります。
個々の CMake
や cargo
といったツールにはプロファイラがあるかもしれませんが、結局知りたいのはビルドプロセス全体の所要時間なので全体をまとめてプロファイルできる必要があります。
さらに、ソフトウェアがビルドされる環境は必ずしもプロファイルしやすい場所ではありません。
よくあるのは CI でビルドしている場合でしょう。
Github Action 上などで perf
や perfetto
などのリッチなプロファイラを設定するのはそれ自体が骨の折れる作業ですし、必要な権限がなくそもそも動かすのが不可能である可能性もあります。
また、ビルド環境を完全に固定するために Docker などのコンテナ環境を利用している場合は、プロファイラのセットアップがさらに面倒になります。
straceprof
straceprof はとにかくお手軽にビルドプロセス全体のプロファイルをとるためのツールです。
プロファイルをとるのに必要なのは strace
コマンドだけです。
このコマンドはほとんどすべての Linux ディストリビューションで簡単にインストールすることができます。
まず、strace
コマンドをつけてビルドしてプロファイルを取ります。
$ strace \
--trace=execve,execveat,exit,exit_group \
--follow-forks \
--string-limit=1000 \
--absolute-timestamps=format:unix,precision:us \
--output=straceprof.log \
<command to profile>
次に、この出力を straceprof
コマンドに渡すとプロファイル結果が可視化されます。簡単ですね!
$ straceprof \
--log=straceprof.log \
--output=straceprof.png
仕組み
strace というコマンドがあります。 このコマンドを利用すると、プロセスが発行する全てのシステムコールを監視し、ファイルに記録することができます。
また、Linux では多くのプロセスが execve(2)システムコールで開始され、exit_group(2)で終了します2。
このため、strace
で各プロセスのexecve(2)
とexit_group(2)
の時間を記録すれば、そのプロセスの所要時間を割り出すことができます。
straceprof
は strace
の出力をパースすることで各プロセスの所要時間を割り出し、matplotlib を使って画像を出力します。
画像の縦方向には意味がなく、可能な限り画像サイズが小さくなる順番にプロセスが並んでいます。
使用例
Julia のビルド
Julia というプログラミング言語をフルビルドしたプロファイラ結果がこちらです。
ビルドを開始してから140秒から320秒の間、compiler.jl
とsys.jl
の処理を行っており、これが全体のボトルネックです。
この処理を高速化できれば、ビルド時間を短縮することができます。
Linux カーネルのビルド
僕がよく使っている Linux カーネルをビルドするスクリプト のプロファイル結果がこちらです。 C言語のコンパイルが並列に行われており、明確なボトルネックはありません。
お願い
https://github.com/akawashiro/straceprof にスターをつけてください。