首页 > 其他分享 >bcc测量函数执行时间

bcc测量函数执行时间

时间:2024-10-31 11:43:01浏览次数:1  
标签:%- 函数 bpf pid 测量 bcc comm data event

获取函数的执行时间对性能分析十分有益,这里给出一个示例来测量kernel 函数的执行时间。

kprobe可用来在函数执行的开始加入探测点,kretprobe可以在函数返回前加入探测点,分别在这个两个探测获取时间,其差值可以作为函数的执行时间。相对ftrace,这种方式要精确很多。下面是一个例子,测量__smp_call_single_queue的执行时间。

#!/usr/bin/python3
from bpfcc import BPF
import time

# BPF program
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>

    struct data_t {
    u64 delta;
    u32 pid;
    u64 ts;
    u64 cpu;
    char comm[TASK_COMM_LEN];
};

BPF_PERF_OUTPUT(events);

BPF_HASH(start, u32);
BPF_HASH(arg0, u32);
int begin(struct pt_regs *ctx, int cpu) {
    struct data_t data = {};
    u64 pid_tgid = bpf_get_current_pid_tgid();
    u32 pid = pid_tgid >> 32;
    u32 tid = (u32)pid_tgid;
    u64 ts, c = 0;

    c = (u64)cpu;

    bpf_get_current_comm(&data.comm, sizeof(data.comm));
    if (data.comm[0] != 's' || data.comm[1] != 'c' || data.comm[2] != 'h')
        return 0;
    arg0.update(&tid, &c);
    ts = bpf_ktime_get_ns();
    start.update(&tid, &ts);
    return 0;
};

int end(struct pt_regs *ctx) {
    struct data_t data = {};
    u32 tid;
    u64 *tsp, ts, delta;
    u64 *cpu;

    ts = bpf_ktime_get_ns();
    tid = (u32)bpf_get_current_pid_tgid();
    data.ts = ts;
    bpf_get_current_comm(&data.comm, sizeof(data.comm));
    if (data.comm[0] != 's' || data.comm[1] != 'c' || data.comm[2] != 'h')
        return 0;

    tsp = start.lookup(&tid);
    if (tsp == 0) return 0;     // check hash value before do next,otherwise, error out on compiling
    start.delete(&tid);

    cpu = arg0.lookup(&tid);
    if (cpu == 0) return 0;
    arg0.delete(&tid);

    data.pid = bpf_get_current_pid_tgid();
    delta = ts - *tsp;
    data.delta = delta;
    data.cpu = *cpu;
    events.perf_submit(ctx, &data, sizeof(data));
    return 0;
};
""")

b.attach_kprobe(event="__smp_call_single_queue", fn_name="begin")
b.attach_kretprobe(event="__smp_call_single_queue", fn_name="end")
# header
print("%-18s %-6s %s %-18s %-18s %-10s %-10s" % ("ELAPS(ns)", "TID", "CALL", "COUNT", "DELTA(ns)", "CUR_CPU", "PEER_CPU"))

count = 0
tstamp = 0
# process event
def print_event(cpu, data0, size):
    global count
    global tstamp
    count += 1
    now = time.time_ns()
    delta = now - tstamp
    tstamp = now
    event = b["events"].event(data0)
    print("%-18d %-6d %-10s %-18d %-18d %-10d %-10d" % (event.delta,
        event.pid, event.comm, count, delta, cpu, event.cpu))

# loop with callback to print_event
b["events"].open_perf_buffer(print_event)
while 1:
    try:
        b.perf_buffer_poll()
    except KeyboardInterrupt:
        exit()

这个例子提供了bcc的多种接口的用法。包含:

  • kprobe和kretprobe;
  • 获取函数入参,c函数的第一个参数指定为struct pt_regs *ctx,他包含了函数入参,上下文等。第二个参数指定探测点的第一个参数。
  • 使用perf buff作为输出:这里使用BPF_PERF_OUTPUT声明一个全局的buff变量,使用perf_submit来向buff加入内容,使用python的bpf库函数open_perf_buffer给输出注册回调函数,使用perf_buffer_poll输出结果;
  • 使用BPF_HASH声明一个map作为全局变量使用,这样就可以在两个c函数之间传递信息,使用update接口添加key,value对,使用lookup接口获取key对应的value,记住,必须检查value是否不为0再做下一步,否则会编译报错,获取value后删除该键值对。
  • 使用bpf_get_current_pid_tgid获取线程tid;
  • 使用bpf_get_current_comm获取用户态命令;
  • 使用bpf_ktime_get_ns获取当前的纳秒时间,记住,在入口点c函数的末尾获取时间,在返回点c函数的开始获取时间,这样测量得到的时间最准确,因为c函数在做一些操作的耗时不可忽略;
  • 开头的from bpfcc import BPF在centos系统上是对的,在ubuntu上需要修改为from bcc import BPF;

本例并不完美,在过滤command时使用了tricky的方法,还需寻找更优雅的方式。

 

标签:%-,函数,bpf,pid,测量,bcc,comm,data,event
From: https://www.cnblogs.com/banshanjushi/p/18517409

相关文章

  • 在 SQL 中,有许多高效、简洁的函数可用于数据处理、查询优化和数据转换。
    以下是一些常见的SQL函数及其详细中文解释、示例和总结:1.COALESCE作用:COALESCE函数从左到右依次检查其参数,并返回第一个非空的值。如果所有参数都为空,则返回NULL。应用场景:可以在处理缺失数据时使用,尤其是多个字段可能为空的情况下,可以选择一个优先级最高的非空值。......
  • No.5 R的基本函数
    一、运算符1.算术运算符%%:求余2.比较运算符==:等于!=:不等于3.逻辑运算符逻辑或|逻辑与&逻辑非!二、数值处理函数1.数学函数abs(a):求a的绝对值sqrt(a):平方根log(a):exp():指数round(a,3):三位小数 2.统计函数mean(a):均值median(a):中位数var......
  • Excel函数之VLOOKUP
    1.介绍VLOOKUP函数是Excel中的一个纵向查找函数,它与LOOKUP函数和HLOOKUP函数属于一类函数,在工作中都有广泛应用,例如可以用来查找数据,按列查找,在多个表格之间核对数据、传递数据,在多个表格之间快速导入数据等函数功能,主要用于查找和检索数据。2.使用VLOOKUP函数语法=VLOOK......
  • 简单介绍一下 if else else if 函数(c基础)
    适合对象c语言初学者 总结语言用色,个人强调用红色,注意为易错点,若有问题请告诉我谢谢。(建议通过目录观看)if函数if函数是条件函数。格式  if接()接  一种语句  执行方法先判断()的真假,若为真,就执行。为假就不执行。if只管距它最近的一个语句或复合语句。 ......
  • 从ICG到SG函数
    SG函数是用于解决博弈论中公平组合游戏(ICG)问题的一种方法ICG这是啥?定义大概就几条:双方参与,轮流决策,决策最优无法决策时游戏结束,无法决策者输,不论如何决策游戏都能在有限步完成同一状态不可多次抵达,游戏无平局,任意决策者在决策点的行为与决策者无关仅与决策点有关这就是I......
  • 【SQL】Hive/Spark SQL笔记之时间函数、环比/同比/时间比较计算
    获取当天:'${zdt.format("yyyy-MM-dd")}'//获取上月月末select'${zdt.lastMonth().format("yyyy-MM-dd")}'T-1上月末select'${zdt.addDay(-1).lastMonth().format("yyyyMMdd")}'1个小时前select'${zdt.addHour(-1)......
  • 【C++】踏上C++学习之旅(四):细说“内联函数“的那些事
    文章目录前言1."内联函数"被创造出来的意义2.内联函数的概念2.1内联函数在代码中的体现2.2普通函数和内联函数的汇编代码3.内联函数的特性(重点)4.总结前言本章来聊一聊C++的创作者"本贾尼"大佬,为什么要创作出内联函数,以及内联函数的定义和内联函数的实现机制等......
  • 介绍一下for break continue 函数(c基础)
    for函数是循环函数格式for(   expression1      ;    expression2    ;     expression3   )+  一种语句expression1初始化变量的值                                         ......
  • qsort函数的学习与使用
    零.导言    在之前的文章中,我介绍了冒泡排序,即按ASCII码值把元素从小到大排序(文章链接我放在了第五部分,有兴趣的小伙伴可以求看看)。而今天我将继续介绍qsort函数,这个函数可以起到和冒泡排序一样的作用,并且有着更加广泛的应用场景。一.qsort函数的定义    qso......
  • Mysql梳理11——聚合函数
    Mysql梳理11——聚合函数Mysql梳理11——聚合函数11.1引言11.2聚合函数介绍11.2.1什么是聚合函数11.2.2聚合函数类型11.2.3聚合函数语法11.3具体聚合函数11.3.1AVG和SUM函数11.3.2MIN和MAX函数11.3.3COUNT函数11.4GROUPBY11.4.1基本使用11.4.2使用多个列......