PCM功能簡介:
Intel-pcm提供了一系列監控CPU核心、Cache、內存控制器和內存DIMM芯片的硬件事件次數,相關寄存器值,硬件性能指標的接口。
主要內容:
主要對外的類和接口集中定義在文件cpucounters.h
,代碼地址爲 https://github.com/opcm/pcm
- 定義了核心PCM類和四種系統狀態類,即
SystemCounterState
,SocketCounterState
和CoreCounterState
和ServerUncorePowerState
。 - 定義了獲取系統狀態的三類接口。
- 獲取當前整個系統範圍的狀態:
SystemCounterState getSystemCounterState()
- 獲取當前某個CPU插槽(socket)範圍的狀態:
SocketCounterState getSocketCounterState(uint32 socket)
- 獲取當前某個CPU(邏輯)核心範圍的狀態:
CoreCounterState getCoreCounterState(uint32 core)
- 獲取當前整個系統範圍的狀態:
- 實現了獲取一段時間內以及特定時刻硬件事件的計數接口。
- 時鐘週期:獲得期間內DRAM和多通道DRAM(MCDRAM),能量控制單元PCU和快速通道互聯(QPI)的時鐘週期數。例如
getDRAMClocks, getMCDRAMClocks, getPCUClocks, getQPIClocks
。 - Performance Monitor Unit (PMU)計數器:獲得期間內內存控制器MC,能量控制單元PCU,以及嵌入式DRAM控制器的PMU計數器值。例如:
getMCCounter, getPCUCounter, getEDCCounter
- Cache訪問:獲得期間內L2和L3 Cache的命中/缺失率、Miss數量,此外還能統計L3 Cache的佔空比,L3 Cache訪問命中次數中由Snoop協議引發的數量。例如
getL2CacheHits, getL2CacheHitRatio, getL3CacheMisses, getL3CacheOccupancy, getL3CacheHitsSnoop
。 - Memory傳輸:
獲得期間內內存傳輸帶寬,處理器從各種內存(包括DRAM、Persistent Memory和嵌入式DRAM)中讀取/寫回的字節總數,對內存的IO請求字節數。例如getLocalMemoryBW, getBytesReadFromMC, getBytesWrittenToMC, getIORequestBytesFromMC
。 - 處理器核心:獲得期間內單個處理器核心/整個系統的IPC、退役指令數、時鐘週期數和平均時鐘頻率。例如
getIPC, getInstructionsRetire, getExecUsage, getCycles, getAverageFrequency
。 - 能耗:獲得期間內處理器和DRAM的耗能數量。例如
getConsumedEnergy, getDRAMConsumedEnergy, getConsumedJoules
。 - Quick-Path Interconnect (QPI): 獲得期間內QPI不同QPI連接之間的數據傳輸量。例如
getIncomingQPILinkBytes, getOutgoingQPILinkBytes
。
- 時鐘週期:獲得期間內DRAM和多通道DRAM(MCDRAM),能量控制單元PCU和快速通道互聯(QPI)的時鐘週期數。例如
使用示例:
-
編譯PCM庫,在linux環境下使用make命令編譯後會在編譯目錄下生成libPCM.a靜態鏈接庫。
-
統計示例代碼造成的L3 Miss和DRAM讀寫數量,示例代碼如下:
/* filename: test.cc */
#include <iostream>
#include <cstdint>
#include "cpucounters.h"
using std::cout;
int main(void) {
//新建一個PCM實例
PCM* pcm_ = PCM::getInstance();
auto status = pcm_->program();
const int TEST_SCALE = 10000;
int * arr = new int[TEST_SCALE];
uint32_t check_sum = 0;
//我們希望監控整個系統的硬件數值
SystemCounterState before_sstate = getSystemCounterState();
for(int i = 0; i < TEST_SCALE; i++) {
check_sum = (check_sum + arr[i]) % (1 << 16 - 1);
}
SystemCounterState after_sstate = getSystemCounterState();
// 獲取區間內的統計數值
std::cout << "\tL3 misses: " << getL3CacheMisses(before_sstate, after_sstate) << "\n"
<< "\tDRAM Reads (bytes): " << getBytesReadFromMC(before_sstate, after_sstate) << "\n"
<< "\tDRAM Writes (bytes): " << getBytesWrittenToMC(before_sstate, after_sstate) << "\n";
delete []arr;
return 0;
}
-
使用命令編譯示例代碼
g++ test.cc -Ipcm -Lpcm -lPCM -pthread -o test
編譯test.cc,其中-I選項添加頭文件目錄pcm,-L選項添加鏈接庫目錄pcm,-l 選項指定靜態鏈接庫libPCM.a。 -
編譯生成後使用命令
modprobe msr
提供訪問Model-Specific Register,MSR的訪問權限。 -
在root權限下運行test可執行文件,得到統計結果。