2023/1/11
✅ 複数の Ruby Thread の観測
✅ GVL の獲得状況
✅ 情報の取得
✅ Visualization
🔜 プロファイラの自動テスト
アプリケーションから提供される情報も含めて可視化することができる機能
他のプロファイラでいうと marker 的なものなど
既存の実装を少し綺麗に書き直した
TimerThreadScheduler は portable の実装のつもりで作っている
世の中の人がどうやって仕事以外にコードを書く時間を捻出しているのか不思議……
k0kubun さんは 8-12 pm ぐらいに作業時間をとっている
timer_create(3) に渡す cpu time clock を得るために pthread_getcpuclockid(3) がほしい
Pf2.start(threads: [th1, th2])
Rack Middleware として作ればその pthread の context で clock_gettime(3) を呼べるのでは
clock_id を返すよりは pthread の ID を返すほうが素直?
code: ruby
profiler = Pf2.start
profiler.stop
Pf2.start(track_new_threads: true) # Thread Hooks の start を見ているだけ
ISUCON ではどう使っていた?
puma が Kernel#fork したタイミングで Pf2.start していた
rspec
spec_helper で start して終わったときに stop するのではだめ?
もし M:N Threads をサポートするなら
ほしいもの: ある Ruby Thread が消費した時間をトラックする方法
wall time なら Thread Hooks で自前で計測できるかもしれない
cpu time は無理そう
便利・適切なプロファイラの差し込みポイントがない & Thread を勝手に作るアプリケーションで必要になっている?
まぁそう
puma, sidekiq 自体
新しいスレッド 既存の
RUBYOPT="-rprofile'" のような形で事前に差し込ませて、track_new_threads を使わせるといいのでは
timer の install がめんどくさいぐらいでは getcpuclockid を取る API の追加は正当化されなさそう
profile_frames は async-signal-safe ではない?
safe とは言ってないけど safe にする努力をしている
コンパイラの最適化で safe じゃなくなるかもしれない
なので a-s-s であるとコメントはしづらい
でも stackprof はシグナルハンドラで読んでるし production で動いている
Future work
Marker
C と Ruby のスタックを融合させるやつ
これを導入するためにプロファイラをリファクタしたくなった
オーバーヘッドを(雑に)測った
Mandelbrot (16 threads, 800 x 800 @ 10 ms (cpu))
- with pf2: 13.263
- without pf2: 12.925
2% ぐらい
Next
冬休みはこんな感じでした(リファクタリングしていたら終わった)
一旦リリースまでやろうと思っていたが間に合わず
最低限の機能で v0.2.0 を出す
Marker 機能はでき次第出す
C と Ruby のスタックの融合は…… その後
v0.1.0 は適当な中身で push してしまっているので使えず
0.2.0 を出したら blog とか書いたりしてみる
中間報告を書かないといけない
誰が読むためのもの?
k0kubun さんは読む
ここまでの進捗をまとめておく
grant@ruby-lang.org に送る