IMC (記憶體集合計數器)

Anju T Sudhakar, 2019 年 5 月 10 日

基本概述

IMC (記憶體集合計數器) 是一種硬體監控工具,用於收集 Nest 級別(片上但脫離核心)、核心級別和執行緒級別的大量硬體效能事件。

Nest PMU 計數器由在 OCC(片上控制器)複合體中執行的 Nest IMC 微程式碼處理。 微程式碼收集計數器資料並將 nest IMC 計數器資料移動到記憶體。

核心和執行緒 IMC PMU 計數器在核心中處理。 核心級別 PMU 計數器為我們提供每個核心的 IMC 計數器資料,執行緒級別 PMU 計數器為我們提供每個 CPU 執行緒的 IMC 計數器資料。

OPAL 從 IMC 目錄獲取 IMC PMU 和支援的事件資訊,並透過裝置樹傳遞給核心。 事件的資訊包含

  • 事件名稱

  • 事件偏移量

  • 事件描述

並且可能也包含

  • 事件比例

  • 事件單位

某些 PMU 可能對其所有支援的事件具有通用的比例和單位值。 對於這些情況,這些事件的比例和單位屬性必須從 PMU 繼承。

記憶體中的事件偏移量是計數器資料累積的位置。

IMC 目錄位於

https://github.com/open-power/ima-catalog

核心在具有相容欄位 ibm,opal-in-memory-countersimc-counters 裝置節點中的裝置樹中發現 IMC 計數器資訊。核心從裝置樹中解析 PMU 及其事件的資訊,並在核心中註冊 PMU 及其屬性。

IMC 示例用法

# perf list
[...]
nest_mcs01/PM_MCS01_64B_RD_DISP_PORT01/            [Kernel PMU event]
nest_mcs01/PM_MCS01_64B_RD_DISP_PORT23/            [Kernel PMU event]
[...]
core_imc/CPM_0THRD_NON_IDLE_PCYC/                  [Kernel PMU event]
core_imc/CPM_1THRD_NON_IDLE_INST/                  [Kernel PMU event]
[...]
thread_imc/CPM_0THRD_NON_IDLE_PCYC/                [Kernel PMU event]
thread_imc/CPM_1THRD_NON_IDLE_INST/                [Kernel PMU event]

要檢視每個晶片的 nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0/ 資料

# ./perf stat -e "nest_mcs01/PM_MCS01_64B_WR_DISP_PORT01/" -a --per-socket

要檢視核心 0 的非空閒指令

# ./perf stat -e "core_imc/CPM_NON_IDLE_INST/" -C 0 -I 1000

要檢視“make”的非空閒指令

# ./perf stat -e "thread_imc/CPM_NON_IDLE_PCYC/" make

IMC 跟蹤模式

POWER9 支援 IMC 的兩種模式,即累積模式和跟蹤模式。在累積模式下,事件計數累積在系統記憶體中。然後,Hypervisor 定期讀取或在請求時讀取釋出的計數。在 IMC 跟蹤模式下,使用事件資訊初始化 64 位跟蹤 SCOM 值。跟蹤 SCOM 中的 CPMCxSEL 和 CPMC_LOAD 指定要監視的事件和取樣持續時間。在 CPMCxSEL 中的每次溢位時,硬體會快照程式計數器以及事件計數,並寫入 LDBAR 指向的記憶體中。

LDBAR 是一個 64 位專用執行緒暫存器,它具有指示硬體是否配置為累積模式或跟蹤模式的位。

LDBAR 暫存器佈局

0

啟用/停用

1

0:累積模式

1:跟蹤模式

2:3

保留

4-6

PB 範圍

7

保留

8:50

計數器地址

51:63

保留

TRACE_IMC_SCOM 位表示

0:1

SAMPSEL

2:33

CPMC_LOAD

34:40

CPMC1SEL

41:47

CPMC2SEL

48:50

BUFFERSIZE

51:63

保留

CPMC_LOAD 包含取樣持續時間。 SAMPSEL 和 CPMCxSEL 確定要計數的事件。 BUFFERSIZE 指示記憶體範圍。 每次溢位時,硬體會快照程式計數器以及事件計數,更新記憶體並重新載入 CMPC_LOAD 值以用於下一個取樣持續時間。 IMC 硬體不支援異常,因此如果記憶體緩衝區到達末尾,它會靜默環繞。

目前,跟蹤模式監視的事件被固定為迴圈。

跟蹤 IMC 示例用法

# perf list
[....]
trace_imc/trace_cycles/                            [Kernel PMU event]

要記錄具有 trace-imc 事件的應用程式/程序

# perf record -e trace_imc/trace_cycles/ yes > /dev/null
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.012 MB perf.data (21 samples) ]

生成的 perf.data 可以使用 perf report 讀取。

使用 IMC 跟蹤模式的優勢

避免了 PMI(效能監控中斷)中斷處理,因為 IMC 跟蹤模式會快照程式計數器並更新到記憶體。 這也為作業系統提供了一種即時進行指令取樣的方式,而無需 PMI 處理開銷。

使用 perf top 時,有無 trace-imc 事件的效能資料。

在沒有 trace-imc 事件的情況下執行 perf top 命令時,PMI 中斷計數。

# grep PMI /proc/interrupts
PMI:          0          0          0          0   Performance monitoring interrupts
# ./perf top
...
# grep PMI /proc/interrupts
PMI:      39735       8710      17338      17801   Performance monitoring interrupts
# ./perf top -e trace_imc/trace_cycles/
...
# grep PMI /proc/interrupts
PMI:      39735       8710      17338      17801   Performance monitoring interrupts

也就是說,使用 trace_imc 事件時,PMI 中斷計數不會遞增。