前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >使用perf/SystemTap分析pagefault

使用perf/SystemTap分析pagefault

原创
作者头像
ICU
发布2022-04-28 13:34:01
3.5K0
发布2022-04-28 13:34:01
举报
文章被收录于专栏:我和你

摘要

pagefault在使用大量内存的场景下是一个不可忽视的性能损耗,而且在用户态中,该行为是透明的,不好分析和测量,因此必须借助外部工具才能分析。

正文

一、perf

我们可以使用perf,很轻松的分析出,哪些代码会经常性的触发pagefault,以及比重。

首先,我们可以使用以下命令采集pagefault发生的次数。

代码语言:javascript
复制
# -I 1000 每1000ms输出一次,
# -a 采集全部CPU上的事件
# -p <pid> 可以指定进程
> perf stat -e page-faults -I 1000 -a
> perf stat -e page-faults -I 1000 -a -p 10102

或者,我们还可以使用FlameGraph更加直观的看到各部分代码触发pagefault的比例:

代码语言:javascript
复制
# 采集进程10102的30秒pagefault触发数据
> perf record -e page-faults -a -p 10102 -g -- sleep 30
# 导出原始数据,此步必须在采集机器上进行,因为需要解析符号。
> perf script > out.stacks
# 下面的步骤就可以移动到其他机器上了
> ./FlameGraph/stackcollapse-perf.pl < out.stacks | ./FlameGraph/flamegraph.pl --color=mem \
    --title="Page Fault Flame Graph" --countname="pages" > out.svg

我们使用浏览器来打开out.svg就可以直观观察了。

二、SystemTap

我们可以使用以下脚本,每 10 秒输出一次相关进程触发的全部pagefault异常的类型与耗时:

代码语言:javascript
复制
#!/usr/bin/stap

/**
 * Tested on Linux 3.10 (CentOS 7)
 */

global fault_entry_time, fault_latency_all, fault_latency_type

function vm_fault_str(fault_type: long) {
    if(vm_fault_contains(fault_type, VM_FAULT_OOM))
        return "OOM";
    else if(vm_fault_contains(fault_type, VM_FAULT_SIGBUS))
        return "SIGBUS";
    else if(vm_fault_contains(fault_type, VM_FAULT_MINOR))
        return "MINOR";
    else if(vm_fault_contains(fault_type, VM_FAULT_MAJOR))
        return "MAJOR";
    else if(vm_fault_contains(fault_type, VM_FAULT_NOPAGE))
        return "NOPAGE";
    else if(vm_fault_contains(fault_type, VM_FAULT_LOCKED))
        return "LOCKED";
    else if(vm_fault_contains(fault_type, VM_FAULT_ERROR))
        return "ERROR";
    return "???";
}

probe vm.pagefault {
	if (pid() == target()) {
		fault_entry_time[tid()] = gettimeofday_us()
	}
}

probe vm.pagefault.return {
	if (!(tid() in fault_entry_time)) next
	latency = gettimeofday_us() - fault_entry_time[tid()]
	fault_latency_all <<< latency
	fault_latency_type[vm_fault_str(fault_type)] <<< latency
}

probe timer.s(10) {
	print("All:\n")
	print(@hist_log(fault_latency_all))
	delete(fault_latency_all)

	foreach (type in fault_latency_type+) {
		print(type,":\n")
                print(@hist_log(fault_latency_type[type]))
        }
        delete(fault_latency_type)
}

完结

以上就是使用perf/SystemTap分析pagefault的内容,欢迎小伙伴们交流讨论。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 摘要
  • 正文
    • 一、perf
      • 二、SystemTap
      • 完结
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档