`
fosa0989
  • 浏览: 109718 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用performance counter读取硬件或软件Event

阅读更多

从Linux Kernel2.6.31版本开始,Linux内核开始提供一个叫__NR_perf_counter_open(最新的版本里叫__NR_perf_event_open)的系统调用。使用这个系统调用我们可以像使用文件一样打开一个Performance counter,通过设置不同的参数让这个Performance Counter统计不同的软件或硬件事件,然后就可以向读文件一样来读取这些事件的统计结果。比如我可以打开一个Performance Counter统计某一个进程的CPU Cache Miss次数。关于如何传递参数构造Performance Counter来统计不同的事件可以看这篇日志: http://tblog29.appspot.com/blog/1004

 

下面是我写的一个小程序,它为每个CPU和每个进程开一个Performance Counter,统计每个CPU上的Cache miss和每个进程上的Cache miss(不能统计每个进程在单个CPU上的事件,详见上边那篇日志)。本代码参考了 perf 的stat部分。运行需要CAP_SYS_ADMIN权限

 

1 mperf.h

/*
 * eperf.h
 *
 *  Created on: Jan 28, 2010
 *      Author: hchen
 */

#ifndef EPERF_H_
#define EPERF_H_
#include <time.h>
#include <asm/unistd.h>
#include "perf_event.h"

#define MAX_COUNTERS		256
#define MAX_NR_CPUS			32
#define PROC		"/proc"
/*
 * We define u64 as unsigned long long for every architecture
 * so that we can print it with %Lx without getting warnings.
 */
typedef unsigned long long u64;
typedef signed long long   s64;
typedef unsigned int	   u32;
typedef signed int	   s32;
typedef unsigned short	   u16;
typedef signed short	   s16;
typedef unsigned char	   u8;
typedef signed char	   s8;

static inline int
sys_perf_event_open(struct perf_event_attr *attr,
		      pid_t pid, int cpu, int group_fd,
		      unsigned long flags)
{
	attr->size = sizeof(*attr);
	//This system call is defined in asm/unistd.h, in the latest linux kernel
	//it's name has been changed to __NR_perf_event_open .
	return syscall(__NR_perf_counter_open, attr, pid, cpu, group_fd, flags);
}

#endif /* EPERF_H_ */

 2 eperf.c

#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <asm/unistd.h>
#include <dirent.h>

#include "eperf.h"

unsigned int verbose = 0;
//event to be countered
static struct perf_event_attr attrs[] = {
  { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CACHE_MISSES	}
};

int nr_counters = 0;
static unsigned int	nr_cpus				=  0; // amount of cpus

static int			inherit				=  1;
static int			scale				=  1;
//used to save performance counter
static int			fd[MAX_COUNTERS];

/*
 * Read out the results of a single counter:
 */
static void read_counter(int counter)
{
	u64 single_count[3];
	size_t res, nv;

	if (fd[counter] <= 0)
		return;

	nv = scale ? 3 : 1;
	res = read(fd[counter], single_count, nv * sizeof(u64));

	if(res == nv * sizeof(u64)){
		if(verbose)
			printf("Counter %d: %llu\n", counter, single_count[0]);
	}else{
		fprintf(stderr, "Fail to read counter %d\n", counter);
	}
}

void close_all_counters(){
	int counter, tn;
	tn = nr_cpus + nr_counters;

	for (counter = 0; counter < tn; counter++){
		if (fd[counter] <= 0)
			continue;

		close(fd[counter]);
		fd[counter] = -1;
	}

}

void run_perf_stat()
{
	int counter, tn;
	tn = nr_cpus + nr_counters;

	for (counter = 0; counter < tn; counter++)
		read_counter(counter);
}

static void create_perf_stat_counter(int counter, int pid, int system_wide)
{
	struct perf_event_attr attr; //cache miss
	memcpy(&attr, attrs, sizeof(struct perf_event_attr));

	if (scale)
		attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
				    PERF_FORMAT_TOTAL_TIME_RUNNING;

	if (system_wide) {
		unsigned int cpu;

		for (cpu = 0; cpu < nr_cpus; cpu++) {
			fd[cpu] = sys_perf_event_open(&attr, -1, cpu, -1, 0);
		}
	} else {
		attr.inherit	     = inherit;
		attr.disabled	     = 0;
		attr.enable_on_exec = 1;

		fd[counter + nr_cpus] = sys_perf_event_open(&attr, pid, -1, -1, 0);
	}
}

int main(int argc, const char **argv)
{
	if(argc > 1)
		verbose = atoi(argv[1]);

	DIR *dir;
	struct dirent *drp;
	int run_count, p, pid;
	struct timespec tim, tim2;
	tim.tv_sec = 1; tim.tv_nsec = 0;

	nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);//the the number of CPU

	int counter = 0;
	/* Open /proc directory */
	if ((dir = opendir(PROC)) == NULL) {
		perror("opendir /proc error!");
		exit(4);
	}

	//create counters for each CPU
	create_perf_stat_counter(-1, 1, 1);

	p = 0;
	while ((p++) < 254) {
		/* Get directory entries */
		while ((drp = readdir(dir)) != NULL) {
			if (isdigit(drp->d_name[0]))
				break;
		}

		if (drp) {
			pid = atoi(drp->d_name);
			create_perf_stat_counter(counter, pid, 0);
			if(fd[counter] != -1)
				counter++;
		}

	}

	nr_counters = counter - 1;
	/* Close /proc directory */
	closedir(dir);

	run_count = 100;
//	for (run_idx = 0; run_idx < run_count; run_idx++) {
	while (1) {
		nanosleep(&tim , &tim2);
		run_perf_stat();
	}

	close_all_counters();

	return 1;
}
 
0
0
分享到:
评论

相关推荐

    performance counter best practice

    it contains the knowledge for the windows performance counter

    A Simple Performance Counter Application

    I've read elsewhere that the actual performance counter names used as constructor parameters are localized, so this code will need to be changed appropriately and recompiled for non-English locales.

    VC使用SDK获取Windows硬件、软件信息

    除了上述基本方法,还可以使用性能计数器(Performance Counter)获取系统性能数据,如CPU利用率、内存使用率等。`QueryPerformanceCounter`和`QueryPerformanceFrequency`函数可以用于精确地测量时间间隔,这对于...

    Performance Counters - VMware Infrastructure 3 SDK

    更多关于如何使用Performance Manager的信息,请参阅VMware Infrastructure SDK编程指南。 ### 结论 性能计数器在VMware Infrastructure 3 SDK中扮演着至关重要的角色,能够帮助用户更好地理解和优化虚拟化环境的...

    The Security and Performance of the Galois Counter Mode GCM of Operation

    2. **硬件友好**:由于GCM的核心操作——有限域内的乘法可以很容易地在硬件中实现,因此GCM非常适合于高速硬件环境,如10Gbps或更高带宽的应用场景。 3. **软件优化**:通过表驱动的方法,GCM在软件中也能达到令人...

    perf_event_p6.rar_event

    在计算机硬件优化领域,性能计数器(Performance Counter)扮演着至关重要的角色。它们是处理器内部的一种硬件机制,用于收集和记录特定事件的发生次数,如指令执行、缓存命中、分支预测等,从而帮助开发者深入理解...

    perf event相关介绍

    其名称源自"Performance Event",在早期被称为"Performance counter",自Linux内核2.6.31版本引入后,逐渐发展成为一个功能强大的性能分析工具集合。 Perf的核心功能是利用PMU(Performance Monitoring Unit)、...

    Performance Counter Tool

    性能计数器工具通过读取操作系统提供的性能计数器数据,可以提供CPU使用率的实时监控,帮助用户识别性能瓶颈和潜在的问题进程。 2. **物理内存使用量**: 物理内存,也称为RAM,是计算机中暂时存储数据的地方。当...

    进程监控软件 Performance Monitor中文版

    这个工具能够帮助用户了解系统中各个进程的运行状态,以及硬件资源的使用情况,对于系统优化、故障排查以及性能瓶颈定位具有重要作用。 **一、基础概念与功能** 1. **进程监控**:Performance Monitor能够显示系统...

    SDK获取Windows硬件、软件信息

    - **注册表(Registry)**:Windows存储许多系统和应用程序设置在注册表中,通过Registry API可以读取或修改这些信息。 - **Management Event Viewer**:用于查看系统事件日志,包括安装、卸载软件的记录。 - **...

    perf_event_amd_iommu.rar_amd_event

    在描述中提到的"Perf: amd_iommu - AMD IOMMU Performance Counter PMU implementation.",这里`Perf`代表Linux性能事件子系统,它是Linux内核中用于性能分析的一个工具。PMU(Performance Monitoring Unit)是硬件...

    如何使用Performance Explorer分析System i的性能问题

    在System i上遇到性能问题时,掌握如何使用Performance Explorer进行分析至关重要。本篇文章将深入探讨Performance Explorer这一工具的使用方法,帮助你诊断和解决System i的性能瓶颈。 Performance Explorer是IBM...

    ants performance profiler 8

    至于压缩包内的文件,"Keygen.exe"可能是一个密钥生成器,用于生成Ants Performance Profiler 8的激活码,这在软件授权过程中是非法的。合法使用软件应通过官方渠道购买。而"DotNETDeveloperBundle.exe"可能是.NET...

    perf_event_server.rar_event

    "perf_event_server"通常指的是一个服务或进程,它负责管理和提供对性能事件的访问,这些事件可以是硬件计数器、软件事件或其他与系统性能相关的指标。 在Linux中,`perf`是一个强大的性能分析工具,能够利用`perf_...

    Windows Performance Analyzer.zip

    - **系统优化:** 对比不同设置下的系统性能,优化硬件配置或调整系统设置。 - **故障排查:** 当系统出现性能问题时,使用WPA定位问题源头,如高CPU占用的进程或异常的系统调用。 - **软件开发:** 开发者可以...

    perf_event_p4.rar_event_xeon

    性能事件是处理器提供的一种机制,允许软件(如操作系统、分析工具或应用程序)监控特定的硬件行为,如指令执行、缓存命中或浮点运算。在Intel的处理器中,这些事件通常通过Performance Monitoring Units (PMUs)来...

    perf_event_p4.rar_event

    在Linux操作系统中,`perf`工具是用来进行性能分析的关键组件,它允许用户收集和分析各种硬件和软件性能指标。`perf_event_p4`是针对P4处理器定制的性能事件接口,用于监控和优化处理器的性能。 在描述中提到的...

    windows系统performance monitor监控进程性能

    ### 使用Windows系统Performance Monitor监控进程性能 #### 一、引言 在现代计算机环境中,确保应用程序及系统的稳定性和性能至关重要。Microsoft Windows操作系统提供了一个强大的工具——Performance Monitor...

Global site tag (gtag.js) - Google Analytics