在 NUMA 架構下要如何監控 QPI / UPI 介面的狀態呢!
測試環境為 CentOS7
什麼是 NUMA ?
多核心的處理器最早是透過對稱多處理 SMP (Symmetric multiprocessing) 的方式,所有的 CPU 核心對於記憶體的存取是共用的,但是當 CPU 核心數太多時反而是一個限制,當不同的處理器需要交換資料時都是透過系統匯流排將資料儲存在記憶體中,但當核心數多時,交換資料變成常態, CPU 與記憶體之間的速度跟不上 CPU 處理的速度.越多的核心反而讓整體效能降低.
因此有了 Intel 的 NUMA (Non-uniform memory access),他把 CPU 與記憶體區分成不同的結點 Node (不同的 CPU 各自擁有記憶體),彼此的 CPU 節點再透過 QPI (Intel QuickPath Interconnect) , UPI(Ultra Path Interconnect) 這個介面做溝通.
圖片出自於 https://access.redhat.com/documentation/zh-tw/red_hat_enterprise_linux/6/html/performance_tuning_guide/main-cpu
一開始以為可以透過 lspci – https://benjr.tw/10851 之類的工具可以看到 QPI / UPI 介面,但卻不如預期.
NUMA 常用的指令 numastat 與 numactl – https://benjr.tw/96788 只能顯示目前狀態無法提供即時的監控.
Intel Memory Latency Checker – https://benjr.tw/99426 可以針對 QPI / UPI 介面作效能測試,但一樣無法提供即時的監控.
後來找到一個工具 Processor Counter Monitor (PCM) 官方網站 https://github.com/opcm/pcm ,下載後 make 就可以使用了.
[root@localhost ~]# unzip pcm-master.zip [root@localhost ~]# cd pcm-master/ [root@localhost pcm-master]# make g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm.cpp -o pcm.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm.cpp > pcm.d g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c msr.cpp -o msr.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 msr.cpp > msr.d g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c cpucounters.cpp -o cpucounters.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 cpucounters.cpp > cpucounters.d g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pci.cpp -o pci.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pci.cpp > pci.d g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c client_bw.cpp -o client_bw.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 client_bw.cpp > client_bw.d g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c utils.cpp -o utils.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 utils.cpp > utils.d g++ -o pcm.x pcm.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-numa.cpp -o pcm-numa.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-numa.cpp > pcm-numa.d g++ -o pcm-numa.x pcm-numa.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-power.cpp -o pcm-power.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-power.cpp > pcm-power.d g++ -o pcm-power.x pcm-power.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-sensor.cpp -o pcm-sensor.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-sensor.cpp > pcm-sensor.d g++ -o pcm-sensor.x pcm-sensor.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-msr.cpp -o pcm-msr.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-msr.cpp > pcm-msr.d g++ -o pcm-msr.x pcm-msr.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-memory.cpp -o pcm-memory.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-memory.cpp > pcm-memory.d g++ -o pcm-memory.x pcm-memory.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-tsx.cpp -o pcm-tsx.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-tsx.cpp > pcm-tsx.d g++ -o pcm-tsx.x pcm-tsx.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-pcie.cpp -o pcm-pcie.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-pcie.cpp > pcm-pcie.d g++ -o pcm-pcie.x pcm-pcie.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-core.cpp -o pcm-core.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-core.cpp > pcm-core.d g++ -o pcm-core.x pcm-core.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-iio.cpp -o pcm-iio.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-iio.cpp > pcm-iio.d g++ -o pcm-iio.x pcm-iio.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt g++ -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 -c pcm-lspci.cpp -o pcm-lspci.o g++ -MM -Wall -g -O3 -Wno-unknown-pragmas -DPCM_USE_PERF -std=c++11 pcm-lspci.cpp > pcm-lspci.d g++ -o pcm-lspci.x pcm-lspci.o msr.o cpucounters.o pci.o client_bw.o utils.o -pthread -lrt
PCM 提供下列幾支工具用來監視目前系統 CPU 的狀態(包含 QPI / UPI , PCIe 與 記憶體…)
執行 pcm.x 需要把 NMI (Non Maskable Interrupt) watchdog 關閉.
什麼是 NMI (Non Maskable Interrupt) 與 watchdog ?
當中斷 Interrupt 為 masked 時 CPU 是可以忽略它的,但是當收到 NMI (Non-maskable interrupts) 中斷時,代表是相當嚴重的硬體錯誤不能被忽略.
而 watchdog (watchdog timer) 是一種計時計,系統必須定時去重置他,當系統沒有去重置時代表系統發生了嚴重錯誤,這時候 watchdog 會發出 NMI 把系統重新啟動.
[root@localhost pcm-master]# ./pcm.x Processor Counter Monitor (2018-03-19 10:19:11 +0100 ID=e7e3dcc) Error: NMI watchdog is enabled. This consumes one hw-PMU counter to disable NMI watchdog please run under root: echo 0 > /proc/sys/kernel/nmi_watchdog or to disable it permanently: echo 'kernel.nmi_watchdog=0' >> /etc/sysctl.conf Access to Processor Counter Monitor has denied (no MSR or PCI CFG space access). [root@localhost pcm-master]# echo 0 > /proc/sys/kernel/nmi_watchdog
- pcm.x
Basic processor monitoring utility (instructions per cycle, core frequency (including Intel(r) Turbo Boost Technology), memory and Intel(r) Quick Path Interconnect bandwidth, local and remote memory bandwidth, cache misses, core and CPU package sleep C-state residency, core and CPU package thermal headroom, cache utilization, CPU and memory energy consumption)Number of physical cores: 8 Number of logical cores: 16 Number of online logical cores: 16 Threads (logical cores) per physical core: 2 Num sockets: 2 Physical cores per socket: 4 Core PMU (perfmon) version: 3 Number of core PMU generic (programmable) counters: 4 Width of generic (programmable) counters: 48 bits Number of core PMU fixed counters: 3 Width of fixed counters: 48 bits Nominal core frequency: 2400000000 Hz Package thermal spec power: 85 Watt; Package minimum power: 40 Watt; Package maximum power: 170 Watt; Socket 0: 2 memory controllers detected with total number of 5 channels. 2 QPI ports detected. Socket 1: 2 memory controllers detected with total number of 5 channels. 2 QPI ports detected. Trying to use Linux perf events... Successfully programmed on-core PMU using Linux perf Socket 0 Max QPI link 0 speed: 16.0 GBytes/second (8.0 GT/second) Max QPI link 1 speed: 16.0 GBytes/second (8.0 GT/second) Socket 1 Max QPI link 0 speed: 16.0 GBytes/second (8.0 GT/second) Max QPI link 1 speed: 16.0 GBytes/second (8.0 GT/second)
- pcm-memory.x
Monitor memory bandwidth (per-channel and per-DRAM DIMM rank) - pcm-pcie.x
Monitor PCIe bandwidth per-socket - pcm-iio.x
Monitor PCIe bandwidth per PCIe device - pcm-numa.x
Monitor local and remote memory accesses - pcm-power.x
Monitor sleep and energy states of processor, Intel(r) Quick Path Interconnect, DRAM memory, reasons of CPU frequency throttling and other energy-related metrics - pcm-tsx.x
Monitor performance metrics for Intel(r) Transactional Synchronization Extensions - pcm-core.x
Query and monitor arbitrary processor core events - pcm-sensor
Front-end for KDE KSysGuard (圖形介面)
但這支程式,有極大的限制, 對於某些Intel CPU並不支援 (尤其ATOM系列)