動機

perf

perf是linux2.6之後就內建的工具,可以對cpu採樣

perf會對cpu抽樣,去看現在cpu上的proc是什麼 perf record -F <how-many-times-should-perf-probe> -e <which-event-want-to-trace> -p <pid> -g -- sleep <how-long-does-perf-keep-profiling>

在linux上採樣還有ebpf可以用,但是最好是在4.10之後的版本用

之後透過其他工具整理成flamegraph

flamegraph

  • x軸
    • 沒有什麼意義,因為重點是stack
      • 但chrome的devtools是時間,所以會變成現在這時間點上有什麼stack
  • y軸
    • stack的深度
    • 最上面就是正在跑的function
    • 從底往上長
  • 顏色
    • 沒有什麼意義
    • 但也可以讓他表示不同的東西,分別用不同的顏色
      • 來源: jvm, c++, kernel…
      • cycle/inst的比重: 看是cycle多(stall),或是都在跑inst
  • 點 => 長方形
    • 就是function在stack中的佔比
    • 所以可以換perf的事件,看在stack中發生的佔比!!
  • 除了追花費時間
    • cxt switch
      • 找blocked proc
    • page fault
      • 找誰在要mem
    • disk io req
      • 找用disk的
    • cpu + off-cpu
      • cpu就是原本誰在跑的flamegraph
      • off-cpu就是看誰睡著的flamegraph
      • ebpf可以把兩個和在一起,看
        • 睡著的理由
        • 睡覺時誰在做事
    • 還可以追tcp event, CPU cache miss(LLC-loads)

常見問題

一般profiler都透過下面兩個東西去走

  1. stack pointer frame(或DWARF)
  2. symbol table
  • stack frame pointer
    • compiler優化會把frame ptr當成一般來用
      • 解法
        • 關掉
        • 改用DWARF
        • 用JIT runtime walker?
          • 這樣看不到kernel
  • inline
    • stack frame會消失
    • 解法
      • 關掉
        • 別,很可怕
      • 限制inline的size (java可以,C能嗎?)
      • runtime支援可選的un-inline (java可以,C能嗎?)
  • perf的stack depth限制
    • 預設127
    • linux4.8之後可以改
  • debug symbol
    • 沒symbol就傻眼
    • 解法
      • 找有dbgsym的同名package裝
      • 自己編有debug symbol的
        • 注意到優化等級,有時候優化會把symbol丟了
          • 可以用針對debug的優化,-Og
      • JIT要由runtime生(java的perf-map-agent)
  • code跑在container上
    • 進不去怎麼perf
    • 解法
      • copy出來需要的東西出來
      • linux4.13的improve

Ref

Brendan Gregg大大的slide 十分明瞭一定要看 Brendan Gregg的flamegraphs blog有實例