我正在运行一个简单的程序,其中:
mem_inst_retired.all_loads:k,mem_inst_retired.all_stores:k -I 200 -p <pid>
这是最小的测试代码:
void access_memory(char *memory) {
// Pin thread to CPU 1
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(1, &cpuset);
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset);
std::mt19937 gen(std::random_device{}());
std::uniform_int_distribution<size_t> dist(0, 2GB - 500);
char buffer[500];
while (!should_stop) {
size_t offset = dist(gen);
memcpy(buffer, memory + offset, 500);
buffer[0]++;
}
}
问题:
我观察到,将采样间隔从 200 毫秒更改为 5 秒,会将每个间隔测量的内核操作从 ~10^5 操作更改为 ~10^7 操作。
以下是执行访问和测量加载/存储活动的简单代码: https://gist.github.com/VinayBanakar/8cd04c5fa03a6895292498d3e3687aac
中断处理程序不会从
current
任务进行上下文切换(直到/除非调度程序决定这样做),因此在定时器和外部硬件中断时,硬件性能计数器保持编程状态(在您的情况下计算内核存储指令)处理程序正在运行。
Linux 的 perf 子系统通过在上下文切换时保存/恢复来虚拟化 PMU(当不处于全系统模式时),就像虚拟化其他进程上下文一样。 每个核心变量
current
指向当前正在该核心上执行的任务。
perf stat
生成最少的中断,因为计数器可以编程为其支持的最高限制,因此溢出事件非常罕见。 与 perf record
不同,您想要足够频繁的中断来收集有意义的统计数据。