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可执行文件,得到统计结果。