alanhc
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # Profiling 取自:Brendan Gregg ![image](https://hackmd.io/_uploads/SJ4zPdOXgg.png) 先概覽一下,右側有顏色的方塊代表在 Linux 的硬體或軟體 Component ,黑字分別是可以用的 tool 去 trace 相關的效能議題。 - 有哪些 tool ? - perf - ... - page faults - major - minor ## 視覺化理解 ```mermaid flowchart LR CPU[🧠 CPU] --> TLB["📘 TLB (快取頁面對應)"] TLB -->|✔ 命中| Cache["⚡ Cache (L1/L2/L3)"] Cache -->|✔ 命中| Data[✅ 成功讀資料] Cache -->|❌ Cache Miss| RAM[🧠 RAM] RAM -->|→ 更新 Cache| Cache TLB -->|❌ TLB Miss| PageTable["📄 Page Table (在 RAM)"] PageTable -->|✔ 有對應頁面| TLBUpdate[📥 更新 TLB] TLBUpdate --> Cache PageTable -->|❌ 沒有記錄| PageFault[🚨 Page Fault] PageFault --> Disk[(💽 Disk / Swap)] Disk -->|→ 載入頁面至 RAM| RAM RAM -->|→ 更新頁表 + TLB| TLBUpdate ``` ## 虛擬記憶體存取流程圖 ``` CPU 存取虛擬地址 VA │ ▼ 查 TLB 有無映射(VA → PA) │ ├─✔ 有映射 → 取出實體位址 PA │ │ │ ▼ │ 查 CPU Cache(L1 → L2 → L3) │ │ │ ├─✔ 有資料 → Cache Hit ✅(最快) │ │ │ └─✘ 無資料 → Cache Miss 🚫 │ │ │ ▼ │ 從 RAM 載入資料 → 更新 Cache → 使用 │ └─✘ 無映射 → TLB Miss │ ▼ 查頁表有無該頁面資訊 │ ├─✔ 有:更新 TLB → 回到查 Cache │ └─✘ 無:**Page Fault** ⚠ │ 通知 OS → 從 Disk/SWAP 載入頁面至 RAM ▼ 更新頁表、TLB → 重啟指令 → 查 Cache ``` ## Page Fault ![image](https://hackmd.io/_uploads/ByMxbna7ll.png) - 程式在執行時,嘗試存取一塊目前不在實體記憶體中的虛擬記憶體頁面,導致處理器產生例外中斷,由作業系統處理。 - backgound - Linux 使用 虛擬記憶體(Virtual Memory):每個進程看到的是獨立的虛擬地址空間 - 作業系統會將虛擬記憶體分割為 一頁一頁(Page),通常是 4KB/頁 - 只有程式實際存取頁面時,才會把它從磁碟載入實體記憶體(lazy loading) | 類型 | 描述 | 是否正常 | | ---------------------- | ------------------------------------------------------ | ---------------------- | | **Minor page fault** | 頁面不在 process 的 page table 中,但已在實體記憶體中(如 shared memory) | ✅ 正常,快速處理 | | **Major page fault** | 該頁尚未載入,必須從磁碟或 swap 中讀取 | ⚠️ 成本高,會造成延遲 | | **Invalid (segfault)** | 試圖存取不存在的頁面,或權限錯誤(如寫入唯讀區) | ❌ 系統會發出 `SIGSEGV`,程式當掉 | ## page fault ``` ┌────────────────────────────┐ │ User Program │ │ ─────────────────────── │ │ int *p = malloc(4096); │ │ p[0] = 123; ← 觸發頁錯誤│ └────────────┬───────────────┘ │ ▼ ┌────────────────────────────┐ │ CPU 檢查 Page Table │ │ → 發現該頁不存在(invalid)│ └────────────┬───────────────┘ │ ▼ ┌────────────────────────────┐ │ 發出 Page Fault 中斷 │ │ → 進入 kernel 模式 │ └────────────┬───────────────┘ │ ▼ ┌────────────────────────────┐ │ Linux Kernel Page Fault Handler │ │ 檢查: │ │ ─ 這個地址合法嗎? │ │ ─ 有權限存取嗎? │ │ ─ 是否是映射檔案? │ └────────────┬───────────────┘ │ 合法 │ 非法(非法記憶體) │ │ ▼ ▼ ┌────────────────────────────┐ ┌────────────────────────────┐ │ 從磁碟 / swap 載入該頁面 │ │ 傳送 SIGSEGV,程式崩潰 │ │ 或從 shared memory 拷貝 │ │ Segmentation Fault 錯誤訊息│ └────────────┬───────────────┘ └────────────────────────────┘ │ ▼ ┌────────────────────────────┐ │ 更新 Page Table(將虛擬頁→實體頁) │ └────────────┬───────────────┘ │ ▼ ┌────────────────────────────┐ │ 程式重新執行剛才那一行 │ │ 成功寫入 p[0] = 123 │ └────────────────────────────┘ ``` - major vs minor ``` ┌────────────┐ │ Page Fault │ └────┬───────┘ ▼ ┌────────────┐ │ 該頁是否已載入? │ └──┬───────────┘ │Yes(在記憶體) ▼ ┌──────────────┐ │ Minor Page Fault │ │ → 建立對應 page table│ └──────────────┘ │No(需從磁碟讀取) ▼ ┌──────────────┐ │ Major Page Fault │ │ → 讀磁碟 → 分配頁面│ └──────────────┘ ``` ## page fault vs cache miss | 項目 | **Page Fault(分頁錯誤)** | **Cache Miss(快取未命中)** | | ----------- | ------------------------ | --------------------------- | | **發生時機** | 存取的虛擬頁面尚未載入至主記憶體(RAM) | 存取的資料不在 L1/L2/L3 cache 中 | | **處理方式** | 由 OS 介入處理,可能從磁碟載入資料至 RAM | 由硬體自動從主記憶體(RAM)載入資料到快取中 | | **成本(延遲)** | 非常高,若需從磁碟(或 swap)載入頁面 | 中等偏低,取決於從哪層 cache 到 RAM 的距離 | | **是否中斷程式** | 是,會觸發 exception,由作業系統處理 | 否,通常程式繼續執行,只是稍慢 | | **發生原因** | 虛擬頁尚未對應至有效的實體記憶體 | 欲讀取的資料未被 cache 命中 | | **與記憶體的關係** | 涉及虛擬記憶體管理與頁面交換 | 涉及 CPU cache 系統與資料區域性 | - 直覺理解: - Cache Miss:像你打開冰箱找牛奶,沒看到 → 去儲藏室(RAM)找到了 → 下次記得先放冰箱。 - Page Fault:你打開冰箱找牛奶,發現牛奶根本沒買 → 出門去超商買回來 → 下次記得先放家裡冰箱。 發生路徑上的關聯: CPU 想要讀某個位址 → 查 TLB 是否有對應實體頁(若無則 TLB miss) 若頁面尚未載入 RAM → Page Fault 若頁面已在 RAM,接下來查 cache → 若不在 cache → Cache Miss 如果在 cache → Cache Hit(最快) 總結一句話: Cache Miss 是 CPU 找資料時,快取裡沒命中,需要去 RAM。 Page Fault 是 CPU 找資料時,那頁根本還不在 RAM,需要作業系統把它從磁碟讀進 RAM。 ## TLB miss ![image](https://hackmd.io/_uploads/SJHjd8Cmel.png) ## TLB ![image](https://hackmd.io/_uploads/Ski0g2pXle.png) ![image](https://hackmd.io/_uploads/H1sIZhTQgx.png) ![image](https://hackmd.io/_uploads/S1dDWn6Qlx.png) [Introduction to Memory Management in Linux](https://youtu.be/7aONIVSXiJ8) ```mermaid flowchart TD subgraph CPU&nbsp;Core ALU[ALU / AGU<br>產生虛擬位址] --> VA[Virtual Addr] VA --> TLB{{TLB<br>快取查詢}} end TLB -- 命中 --> MEM[👉 實體記憶體存取] TLB -- 未命中 --> MMU[MMU<br>分頁表走訪] MMU -- 合法 PTE --> FILL[回填 TLB] --> MEM MMU -- 不存在 / 權限錯誤 --> PF[⚡ Page&nbsp;Fault] PF --> OS["OS Page-Fault&nbsp;Handler<br>(核心模式)"] OS -->|換頁 / 配頁| PTU[更新分頁表<br>+ 刷新 TLB] PTU --> RET[返回使用者態,重新執行指令] ``` | 項目名稱 | 中文名稱 | 說明 | 常見用途 | | ------------------ | --------- | --------------------------------------------- | ------------------------ | | `cycles` | CPU 週期數 | 處理器執行的總時鐘週期數 | 評估程式執行時間(與 CPU 頻率相關) | | `instructions` | 指令數 | 已執行的 CPU 指令總數 | 搭配 cycles 計算 IPC(每週期指令數) | | `minor-faults` | 次級缺頁 | 記憶體頁已存在但尚未映射進行處理(無需 I/O) | 分析虛擬記憶體效能 | | `major-faults` | 重大缺頁 | 缺頁時需從磁碟讀取資料(需進行 I/O) | 檢查是否頻繁觸發記憶體分頁 | | `dTLB-loads` | 資料 TLB 載入 | 嘗試載入資料的 TLB(Translation Lookaside Buffer)記錄次數 | 檢查記憶體虛實轉換快取的使用狀況 | | `dTLB-load-misses` | 資料 TLB 失敗 | 資料存取時未命中 TLB,需查詢頁表 | 觀察 TLB 效率,失敗率高表示轉換緩慢 | | `iTLB-loads` | 指令 TLB 載入 | 嘗試載入指令的 TLB 次數 | 評估程式碼虛擬位址快取命中率 | | `iTLB-load-misses` | 指令 TLB 失敗 | 指令存取時未命中 TLB,需查詢頁表 | 指令分頁效率分析,常見於大型 binary | | `page-faults` | 頁面錯誤總數 | 包含 minor 與 major fault 的總數 | 觀察程式在記憶體管理上的負擔 | | `cache-references` | 快取存取次數 | CPU 對 L1/L2/LLC 等快取的總存取次數 | 衡量快取使用頻繁程度 | | `cache-misses` | 快取未命中次數 | CPU 存取快取時未命中的次數 | 評估資料/指令是否常被 cache 命中 | - perf - sudo perf stat - sudo perf record -g - - TODO - gprof | 階段 | 目的 | 常用指令 / 工具 | | -------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ | | **快速量化 (粗粒度)** | 先確認 CPU/記憶體/IO 是否飽和,判斷是哪一類瓶頸 | `top`、`htop`、`vmstat`、`iostat`、`dstat` | | **抽樣分析 (中粒度)** | 找出「最耗時的函式/路徑」 | `perf stat / top / record + report`、`BPFtrace`、`FlameGraph` | | **精細診斷 (細粒度)** | 深入微架構(Cache、分支、TLB 等)、鎖競爭、系統呼叫 | `perf stat -e ...`、`perf annotate`、`perf c2c / lock`、`ftrace`、`eBPF + BCC/BPFtrace`、`valgrind` (massif/cachegrind) | perf、ftrace、eBPF、kgdb、kprobes ### Links - [A Beginner's Guide to Linux Performance Profiling: From First Principles to Flamegraphs](https://hackmd.io/@alanhc/profiling-101) - gui - [Profiling CPU and Memory on Linux, with Opensource Graphical Tools - David Faure, KDAB - linux foundation](https://youtu.be/HOR4LiS4uMI) - [Inspecting and Optimizing Memory Usage in Linux - João Marcos Costa, Bootlin](https://youtu.be/pIR1H7ZyWe4) - ["Tracing, Profiling & Debugging in Production (eBPF)" - Trent Lloyd (PyCon AU 2019)](https://youtu.be/jXzEzmz-oag) - [Linux Performance Tools, Brendan Gregg, part 1 of 2](https://youtu.be/FJW8nGV4jxY) - [Velocity 2017: Performance Analysis Superpowers with Linux eBPF](https://youtu.be/bj3qdEDbCD4?si=bt9DVyikG1jHfmXt) 效能分析的本質是: > 🔑 效能(Performance)= 有用的工作(Useful Work)÷ 所花的時間(Time) 換句話說: - 我們的程式到底做了多少有意義的工作? - 做這些工作的過程中花掉的時間在哪裡? - 如果慢,到底慢在什麼資源?如何確認? ## 什麼是效能? 效能可以被分解為最根本的三個資源維度: | 資源類型 | 代表指標 | 第一性原理的根本限制 | |----------------|-------------------------------|-------------------------------------------| | **CPU** | 指令數量、IPC、使用率 | CPU 是有限的時脈驅動狀態機,只能每 cycle 做有限工作 | | **Memory** | cache miss、TLB、page fault | 記憶體存取受到階層結構與時延限制(memory wall) | | **I/O** | IO wait、latency | 裝置響應時間、佇列設計、吞吐量有限 | | 資源類型 | 第一性限制(根本物理限制) | 常見瓶頸現象 | | ------- | ---------------------- | ------------------------------- | | 🖥️ CPU | 每個 cycle 執行固定數量的指令 | CPU 飽和、IPC 太低 | | 💾 記憶體 | 存取速度受到階層結構與 latency 限制 | Cache miss、Memory wall、TLB miss | | 🔄 I/O | 外部裝置存取速度受限於硬體 | I/O wait、device latency | ## 為何要進行效能分析? 在資源限制的前提下,盡可能提升有用工作的比例,減少無效等待或浪費。 ## 效能劣化的基本來源有哪些?(來自物理與系統設計限制) | 基本現象 | 第一性原因解釋 | |---------------------|----------------------------------------------------------| | CPU 飽和 | 指令數量過多、無法並行處理、等待其他資源(如記憶體) | | Cache Miss | 資料位置分散、不符合 spatial/temporal locality | | Page Fault | 虛擬記憶體機制導致非預期 I/O(memory access latency) | | Context Switch | 多任務切換導致保存/還原狀態、TLB/cache flush 等 overhead | | Lock Contention | 多執行緒同時搶奪資源,造成序列化 | | I/O Bottleneck | 磁碟、網路等裝置 throughput 無法滿足需求 | ## 效能分析的工具選擇與使用時機 | 階段 | 你在問的問題 | 常見工具 | 工具特性 | | ----------- | ----------------------- | ------------------------------------------- | --------------- | | ① 基本時間量測 | 程式整體到底花多少時間? | `time`, `hyperfine` | 快速簡單,取得初步效能數據 | | ② 系統資源使用 | CPU/Memory/I/O 哪個資源是瓶頸? | `top`, `htop`, `vmstat`, `iotop` | 快速定位整體瓶頸資源 | | ③ CPU 細部分析 | IPC 高嗎?Cycles 浪費在哪? | `perf stat`, `ocperf`, `pmu-tools` | 提供細緻的 CPU 硬體指標 | | ④ 熱點函式定位 | 哪個函式或程式段落最耗時? | `perf record/report`, `gprof`, `FlameGraph` | 提供函式級別精確定位 | | ⑤ 函式呼叫關係 | 函式呼叫誰、多少次、每次多久? | `uftrace`, `ltrace` | 清楚展示 call graph | | ⑥ 記憶體耗用 | 記憶體用多少?峰值在哪裡? | `valgrind massif`, `heaptrack` | 檢查記憶體峰值、leak | | ⑦ Cache行為分析 | L1/L2 cache有效使用嗎? | `cachegrind`, `callgrind`, `perf c2c` | 展示 Cache 細部效能 | | ⑧ 低負擔線上追蹤 | Production 可用的長期低成本追蹤? | `eBPF` (`bcc`, `bpftrace`) | 長期觀測,幾乎不影響效能 | ## 整體分析流程(效能分析 Roadmap) ```mermaid graph LR A[① 量化整體時間 time/hyperfine] --> B[② 觀察資源使用 top/iotop] B --> C[③ 深入 CPU 指標 perf stat] C --> D[④ 熱點函式 perf record + FlameGraph] D --> E[⑤ 函式呼叫關係 uftrace] E --> F[⑥ 記憶體峰值 massif] F --> G[⑦ Cache 行為 cachegrind] G --> H[⑧ 長期追蹤 eBPF/bpftrace] ``` ## 分析流程 1. **觀察輸出行為** - 為什麼慢?延遲在哪? - 常用指標:wall-clock time、throughput、latency 2. **建立模型** - T = CPU Time + Wait Time + I/O Time - CPU Time = Instructions / IPC × Cycle Time 3. **找出資源瓶頸** - 工具:perf、uftrace、ftrace、top、iotop、vmstat 等 4. **回推到根本原因** - 是不是 cache miss?是不是鎖?是不是 syscall?是不是 scheduler 不公平?是不是 memory bandwidth 被佔用? 5. **優化策略根據本質制定** - 減少 I/O 次數(避免 page fault) - 減少 thread 間 contention(使用 lock-free 結構) - 利用資料 locality(避免 cache miss) - 改寫演算法使得計算時間減少(例如 FFT vs naive DFT) ### perf #### 用途 `perf` 是 Linux 下用於分析效能瓶頸的核心工具,適用於從系統層級到函式層級的 CPU profiling、cache miss 分析與系統事件統計。 #### 使用時機 - 想知道「哪裡跑得最久」:找出 CPU 熱點與 call graph - 想知道「整體是否有效率」:透過 `perf stat` 觀察 IPC、cache miss、cycles - 需要生成火焰圖以視覺化熱點區段時 - 觀察 kernel 與 userspace 混合行為 #### 常見用法 ```bash # 統計整體效能指標(IPC、cache miss 等) perf stat ./your_program # 收集 call graph 與 hot spot 分析 perf record -g ./your_program perf report # 火焰圖:輸出資料並產生視覺圖形 perf record -F 99 -a -g -- ./your_program perf script > out.perf stackcollapse-perf.pl out.perf > out.folded flamegraph.pl out.folded > flamegraph.svg ``` #### 優點 - 不需修改程式即可進行 profiling - 支援多種硬體事件(如 instructions、cycles、cache miss) - 可深入分析 kernel 與 user 空間行為 - 可輸出火焰圖等視覺化工具 #### 缺點 - 有些功能需 root 權限執行 - 精確分析需符號表與 debugging symbols - 在 container 或 restricted 環境下可能受限 #### 實務建議 - 進行任何優化前,先用 `perf stat` 量化基本效能 - 用 `perf top` 即時觀察熱點,再進行 `perf record` 深入分析 - 建議搭配火焰圖視覺化觀察瓶頸集中區域 - 生產環境建議短時取樣,避免過多 overhead ### ftrace #### 用途 `ftrace` 是 Linux kernel 內建的 tracing framework,用於追蹤核心行為(context switch、IRQ latency、function call、syscall 等),可幫助系統工程師深入分析排程延遲、系統抖動(jitter)與低階效能問題。 #### 使用時機 - 排查系統異常抖動、長時間卡住的 root cause - 驅動程式與 kernel module 的效能瓶頸分析 - 觀察 scheduler 運作、task 切換行為 - 和 `perf` 搭配進行全系統觀察 #### 常見用法 ```bash # 啟用 function tracer sudo echo function > /sys/kernel/debug/tracing/current_tracer # 過濾特定函式,例如 do_sys_open sudo echo do_sys_open > /sys/kernel/debug/tracing/set_ftrace_filter # 啟動與觀察 trace sudo cat /sys/kernel/debug/tracing/trace # 清除 trace buffer sudo echo > /sys/kernel/debug/tracing/trace ``` 也可透過 wrapper 工具如 `trace-cmd`、`kernelshark` 提供更佳的使用體驗與 GUI 支援。 #### 優點 - 原生支援於 kernel,無需額外安裝 - 能夠精確觀察 scheduler 與 interrupt 層級活動 - 適合分析 low-latency 系統與 driver - 支援多種 tracer(function、irqsoff、sched_switch 等) #### 缺點 - 操作複雜,需要熟悉 debugfs 與 kernel trace 環境 - 輸出資訊可能過於繁雜,需搭配過濾條件使用 - 僅適用於 kernel space,不適合使用者空間 profiling #### 實務建議 - 若觀察 jitter 或 latency spike,先從 `sched_switch` 分析上下文切換時間 - 可搭配 `trace-cmd report` 彙整更清晰的事件序列 - 驅動或 kernel module 最佳化常需搭配 `ftrace` 佐證 ### 火焰圖分析(Flamegraph) #### 用途 火焰圖是一種視覺化工具,用於顯示 CPU 使用的函式堆疊與時間分佈。它可以幫助你一眼看出哪些函式佔用最多執行時間,適合用於分析 hot path 與瓶頸函式。 #### 使用時機 - 程式效能下降但原因不明 - 想快速定位執行時間集中在哪些函式 - 與團隊溝通效能瓶頸時需要可視化證據 - 對函式調用深度與寬度有整體認知需求 #### 建立流程(以 perf 為例) ##### 安裝工具(以 Ubuntu 為例) ```bash sudo apt install linux-tools-common linux-tools-$(uname -r) \ git build-essential -y # 安裝 flamegraph 腳本集 git clone https://github.com/brendangregg/Flamegraph.git cd Flamegraph ``` ##### 收集資料並產出圖表 ```bash # 收集 profile 資料(建議搭配 -F 控制取樣頻率) perf record -F 99 -a -g -- ./your_program # 轉換成 stack trace 格式 perf script > out.perf # 產出 flamegraph 所需格式 ./stackcollapse-perf.pl out.perf > out.folded # 繪製火焰圖 ./flamegraph.pl out.folded > flamegraph.svg ``` #### 火焰圖說明 - **橫向長度**:表示總執行時間佔比(越長越慢) - **縱向堆疊**:表示函式呼叫鏈深度 - **每一條方塊**:表示一個函式,可滑鼠懸停看名稱與時間 #### 優點 - 非常直觀、便於發現效能熱點(hot path) - 不需修改原始碼,可在已編譯程式上取樣 - 適合大規模應用程式的全域視角效能分析 #### 缺點 - 須搭配 `perf` 或其他 trace 工具收集資料 - 多執行緒與 async 程式容易堆疊混亂,需清理堆疊資料 - 需花時間學習解讀技巧 #### 實務建議 - 可定期在開發週期進行一次火焰圖分析做為基準比較 - 遇到 CPU 使用異常高時優先繪製火焰圖定位 - 可搭配分支、cache miss 事件產生不同維度火焰圖 ### valgrind #### 用途 `valgrind` 是一套動態分析工具,最常用於記憶體錯誤偵測、資源洩漏分析與 cache 效能模擬。 核心工具包含: - `memcheck`: 偵測未初始化記憶體讀取、非法存取、記憶體洩漏等問題 - `cachegrind`: 分析 cache miss、分支預測命中率 - `callgrind`: 分析函式呼叫次數與執行時間(可搭配 KCachegrind 視覺化) #### 使用時機 - 開發早期測試記憶體正確性與釋放邏輯 - 找出 segmentation fault 原因 - 想量化不同演算法對 cache 行為的影響(例如排序) - 搭配 `callgrind` 作為簡易函式 profiling 工具 #### 常見用法 ```bash # 偵測記憶體使用錯誤與洩漏 valgrind --leak-check=full ./your_program # 偵測未初始化記憶體、越界存取 valgrind --track-origins=yes ./your_program # 分析 cache 行為 valgrind --tool=cachegrind ./your_program cg_annotate cachegrind.out.* # 函式呼叫分析 valgrind --tool=callgrind ./your_program callgrind_annotate callgrind.out.* ``` #### 優點 - 偵錯能力強,可定位難以重現的記憶體問題 - 可模擬硬體 cache 行為,便於調整資料結構或演算法 - callgrind 與 cachegrind 支援詳細報告與視覺化工具(如 KCachegrind) #### 缺點 - 執行非常慢,通常為原始速度的 10~50 倍 - 不支援多執行緒間同步錯誤偵測 - 僅支援 x86/x86_64 架構,其他平台相容性差 #### 實務建議 - 開發初期強烈建議整合至測試流程中,提早發現潛藏 bug - 對效能敏感邏輯(如排序、數值計算)可搭配 `cachegrind` 模擬最佳化潛力 - 呼叫行為分析可導出 callgrind 檔並使用 KCachegrind 互動視覺化分析 ### gdb + core dump 分析流程 #### 為何需要? 在生產環境中,程式可能會因為 segmentation fault、abort、assertion fail 等異常崩潰。當你無法重現這些錯誤時,**core dump 是唯一可以還原當下狀態的線索來源**。 使用 `gdb` 搭配 core dump 可以: - 查看崩潰當下是哪一行程式碼造成的錯誤 - 還原呼叫堆疊(stack trace)與變數內容 - 檢查記憶體狀態與指標有效性 - 協助判斷邏輯錯誤、資源釋放順序等問題 #### 使用時機 - 程式 crash 且無法用 valgrind 或 log 重現時 - 使用者回報錯誤但無法完整還原操作流程時 - CI/CD 環境中需自動收集失敗樣本進行事後分析 #### 如何啟用 core dump? ```bash # 設定 core dump 開啟與檔案大小(ulimit 預設為 0) ulimit -c unlimited # 指定 core 檔儲存路徑(Linux) echo "/tmp/core.%e.%p" | sudo tee /proc/sys/kernel/core_pattern ``` #### 撰寫可除錯的程式(加上 debug symbol) ```bash g++ -g -o myprog main.cpp ``` #### 使用 gdb 分析 core dump ```bash # 假設 myprog 是執行檔,core.12345 是 dump 檔 gdb ./myprog core.12345 # 在 gdb 內常用指令: (gdb) bt # 顯示 backtrace(函式呼叫堆疊) (gdb) frame 0 # 切到崩潰當下的堆疊框架 (gdb) info locals # 查看區域變數 (gdb) list # 顯示錯誤行附近原始碼 ``` #### 優點 - 還原問題現場,不必重現也能追蹤 root cause - 可搭配 CI/CD 自動收集並分類 crash case - 支援多種架構與平台(cross-debug 也可) #### 缺點 - 需事先保留 core 檔與 debug symbol - 無法分析邏輯錯誤(只能抓 runtime 異常) - 不適合即時效能 profiling(但可作為後續定位工具) #### 實務建議 - 開發階段加入 `-g` 編譯選項與 `INHIBIT_PACKAGE_STRIP = "1"`(如 Yocto) - 保留執行檔與 core dump,並統一命名便於自動分析 - 可撰寫腳本自動用 gdb 對 core dump 執行 `bt` 並儲存堆疊 ## TODO - vmstat 1 - iostat 1 - network - netstat -a - sar - mpstat 1 - pidstat

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully