V8 的 Linux perf 整合

V8 內建支援 Linux perf 工具。它是由 --perf-prof 命令列選項啟用。
V8 會在執行期間將效能資料寫入檔案,該檔案可與 Linux perf 工具一起用來分析 V8 的 JIT 編譯碼(包括 JS 函式名稱)效能。

需求 #

建置 V8 #

若要使用 V8 與 Linux perf 的整合,您需要使用 enable_profiling = true gn 旗標建置它

echo 'enable_profiling = true' >> out/x64.release/args.gn
autoninja -C out/x64.release

使用 linux-perf-d8.pyd8 進行剖析 #

建置 d8 之後,您可以開始使用 linux perf

tools/profiling/linux-perf-d8.py out/x64.release/d8 path/to/test.js;

更完整的範例

echo '(function f() {
var s = 0; for (var i = 0; i < 1000000000; i++) { s += i; } return s;
})();'
> test.js;

# Use custom V8 flags and a separate output dir for less clutter:
mkdir perf_results
tools/profiling/linux-perf-d8.py --perf-data-dir=perf_results \
out/x64.release/d8 --expose-gc --allow-natives-syntax test.js;

# Fancy UI (`-flame` is googler-only, use `-web` as a public alternative):
pprof -flame perf_results/XXX_perf.data.jitted;
# Terminal-based tool:
perf report -i perf_results/XXX_perf.data.jitted;

查看 linux-perf-d8.py --help 以取得更多詳細資料。請注意,您可以在 d8 二進位元組引數之後使用所有 d8 旗標。

使用 linux-perf-chrome.py 對 Chrome 或 content_shell 進行剖析 #

  1. 您可以使用 linux-perf-chrome.py 腳本對 chrome 進行剖析。請務必加入 必要的 chrome gn 旗標 以取得正確的 C++ 符號。

  2. 建置準備好之後,您可以使用 C++ 和 JS 程式碼的完整符號對網站進行剖析。

    mkdir perf_results;
    tools/profiling/linux-perf-chrome.py out/x64.release/chrome \
    --perf-data-dir=perf_results --timeout=30
  3. 導覽至您的網站,然後關閉瀏覽器(或等待 --timeout 完成)

  4. 退出瀏覽器後,linux-perf.py 會後處理檔案,並顯示一個清單,其中包含每個渲染器程式的結果檔案

    chrome_renderer_1583105_3.perf.data.jitted      19.79MiB
    chrome_renderer_1583105_2.perf.data.jitted       8.59MiB
    chrome_renderer_1583105_4.perf.data.jitted       0.18MiB
    chrome_renderer_1583105_1.perf.data.jitted       0.16MiB
    

探索 linux-perf 結果 #

最後,您可以使用 Linux perf 工具探索 d8 或 chrome 渲染器程式的剖析

perf report -i perf_results/XXX_perf.data.jitted

您也可以使用 pprof 產生更多視覺化效果

# Note: `-flame` is google-only, use `-web` as a public alternative:
pprof -flame perf_results/XXX_perf.data.jitted;

低階 linux-perf 使用法 #

直接使用 linux-perf 與 d8 #

根據您的使用案例,您可能想要使用 d8 直接使用 linux-perf。
這需要一個兩步驟的程序,首先 perf record 會建立一個 perf.data 檔案,必須使用 perf inject 進行後處理,以注入 JS 符號。

perf record --call-graph=fp --clockid=mono --freq=max \
--output=perf.data
out/x64.release/d8 \
--perf-prof --no-write-protect-code-memory \
--interpreted-frames-native-stack \
test.js;
perf inject --jit --input=perf.data --output=perf.data.jitted;
perf report --input=perf.data.jitted;

V8 linux-perf 旗標 #

--perf-prof 用於 V8 命令列,以記錄 JIT 程式碼中的效能範例。

--nowrite-protect-code-memory 是必要的,用於停用程式碼記憶體的寫入保護。這是必要的,因為當 perf 看見從程式碼頁面移除寫入位元的事件時,它會捨棄有關程式碼頁面的資訊。以下是一個從測試 JavaScript 檔案中記錄範例的範例

--interpreted-frames-native-stack 用於為已詮釋函數建立不同的進入點(InterpreterEntryTrampoline 的複製版本),以便 perf 可以根據位址來區分它們。由於必須複製 InterpreterEntryTrampoline,因此會造成輕微的效能和記憶體回歸。

直接使用 linux-perf 與 chrome #

  1. 您可以使用相同的 V8 旗標來分析 chrome 本身。按照上述說明取得正確的 V8 旗標,並將 必要的 chrome gn 旗標 加入您的 chrome 建置。

  2. 建置準備好之後,您可以使用 C++ 和 JS 程式碼的完整符號對網站進行剖析。

    out/x64.release/chrome \
    --user-data-dir=`mktemp -d` \
    --no-sandbox --incognito --enable-benchmarking \
    --js-flags='--perf-prof --no-write-protect-code-memory --interpreted-frames-native-stack'
  3. 啟動 chrome 後,使用工作管理員找出渲染程序 ID,並使用它來開始分析

    perf record -g -k mono -p $RENDERER_PID -o perf.data
  4. 導覽至您的網站,然後繼續下一節,了解如何評估效能輸出。

  5. 執行結束後,將從 perf 工具收集到的靜態資訊與 V8 輸出的 JIT 程式碼效能範例結合

    perf inject --jit --input=perf.data --output=perf.data.jitted
  6. 最後,您可以使用 Linux perf 工具來探索

建置 perf #

如果您有過時的 linux 核心,您可以在本地端建置具有 jit 支援的 linux-perf。

在以下步驟中,將 perf 呼叫為 some/director/tip/tools/perf/perf