OProfile支持两种采样方式:基于事件的采样(Event Based)和基于时间的采样(Time Based)。基于事件的采样是OProfile只记录特定事件(比如L2缓存未命中)的发生次数,当达到用户设定的定值时Oprofile就记录一下〈采一个样)。这种方式需要CPU内部有性能计数器(Performace Counter)。基于时间的采样是OProfile借助OS时钟中断的机制,在每个时钟中断,OProfile都会记录一次(采一次样)。引入它的目的在于,提供对没有性能计数器的CPU的支持,其精度相对于基于事件的采样要低,因为要借助OS时钟中断的支持,对于禁用中断的代码,OProfile不能对其进行分析。OProfile在Linux上分两部分,一个是内核模块(oprofile.ko),另一个是用户空间的守护进程( oprofiled)。前者负责访问性能计数器或者注册基于时间采样的函数,并将采样值置于内核的缓冲区内。后者在后台运行,负责从内核空间收集数据,写入文件。其运行步骤如下:1)初始化opcontrol--init 2)配置opcontrol--setup--event=... 3)启动opcontrol--start 4)运行待分析的程序xxx 5)取出数据 6)分析结果opreport-1./xxx
用GNU gprof可以打印出程序运行中各个函数消耗的时间,以帮助程序员找出众多函数中耗时最多的函数还可产生程序运行时的函数调用关系,包括调用次数,以帮助程序员分析程序的运行流程。GNU gprof的实现原理:在编译和链接程序的时候(使用-pg编译和链接选项),gcc在应用程序的每个函数中都加入名为mcount (_mcount或_mcount,依赖于编译器或 *** 作系统)的函数,也就是说应用程序里的每一个函数都会调用mcount,而mcount会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间、调用次数等的所有信息。
程序刚开始运行时,一个进程(父进程) A, 第一次 fork 后,产生子进程 B此时,
A 中的 pid1 = B的pid
B 中的 pid1 = 0
然后 A B 分别进行第二次 fork, 分别产生 Ac Bc 两个子进程,此时
A 中的 pid1 = B的pid, pid2 = Ac 的pid
Ac 中的 pid1 = B 的pid, pid2 = 0
B 中的 pid1 = 0, pid2 = Bc 的pid
Bc 中的 pid1 = 0, pid2 = 0
所以只有 Bc 进程会打印 printf(“A:my pid is:%d\n”,getpid())
只有Ac 会打印 printf(“B:my pid is:%d\n”,getpid())
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)