使用Perf插件跟踪进程切换信息原创
CPU 使用率是最直观和最常用的系统性能指标,是在排查性能问题时会关注的第一个指标。而在导致CPU使用率过高的因素中,进程切换问题也是非常常见的。进程上下文切换次数较多的情况下,很容易导致CPU 将大量时间消耗在寄存器、内核栈、页表等资源的保存和恢复上,以至于导致系统性能不能充分利用。
但进程切换次数过多或切换次数异常的时候,针对C/C++程序调式手段非常有限,很难找到进程切换的原因,Perf插件本身可以跟踪进程切换调用栈并进行统计,下面用个简单例子测试下:
#include <pthread.h>
#include <unistd.h>
void sleep2()
{
int i = 0;
for (;i<100000;i++)
{
usleep(2500000);
printf("---%d---usleep 25000...\n",i);
}
printf("sleep2 10000 finished\n");
}
void sleep1()
{
sleep2();
}
void *thread1(void *arg)
{
printf("hello from the thread\n");
sleep1();
pthread_exit(NULL);
}
int main()
{
int rc, stat;
int i=0;
for(; i<1; i++)
{
rc = pthread_create(NULL, NULL, thread1, NULL);
if (rc == -1) {
perror("error in pthread_create");
return rc;
}
rc = pthread_join(thid, (void *)&stat);
return 0;
}
通过perf record 命令追踪⼀下进程的切换情况
-ag 记录调⽤栈
-p 指定进程pid
-e 要记录的事件, 本例中为 context-switches
追踪结束后通过report命令来查看进程切换信息的报告
可以看到该报告中总共抓到该进程主动切换了10次,全部是由sleep1 函数调用 sys_nanosleep函数切换进程的。
我们测试一个复杂的例子使用fio模拟大量io
./fio -filename=/home/admin/xinglu/fiotest/testdir/filetest -thread -rw=randrw -rwmixread=70 -ioengine=psync -bs=16k -size=16G -numjobs=10 -runtime=100 -group_reporting -name=mytest
通过上述命令可以发信fio进程的切换集中在文件io的等待操作,相关报告和调用栈如下:
大家在碰到系统进程进程切换次数异常的问题时可以借助Perf工具,排查出具体函数。
XPocket下载地址:https://xpocket.perfma.com/docs/download/
Perf插件下载地址:https://plugin.xpocket.perfma.com/plugin/57