利用strace追踪程序系统调用情况

命令

strace -c 程序

使用该命令即可获取该程序执行过程中每一系统调用的所执行的时间,次数和出错的次数等。

结果及分析

记录器

记录器结果

strace: Process 22088 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.143984       23997         6         1 futex
  0.00    0.000000           0         7           read
  0.00    0.000000           0         9           write
  0.00    0.000000           0         7           close
  0.00    0.000000           0        24        21 stat
  0.00    0.000000           0         9           fstat
  0.00    0.000000           0         1           lseek
  0.00    0.000000           0        21           mmap
  0.00    0.000000           0        16           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         1           ioctl
  0.00    0.000000           0         1           writev
  0.00    0.000000           0         7         7 access
  0.00    0.000000           0         7           shmget
  0.00    0.000000           0         7           shmat
  0.00    0.000000           0         4           clone
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           gettid
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0        42        34 openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.143984                   183        63 total

记录器分析

占比时间最多的系统调用为futex,到达了100%的系统调用时间占用,共计0.14s,futex是和互斥锁相关的系统调用,由于多个线程要对同一个队列进行读写,因此我使用了互斥锁,这么来看互斥锁的效率还是非常高的,效果完全在可以接收的范围内。而write系统调用仅使用了7次,说明boost的过滤流是自带缓冲区的,当缓冲区满时才会真正调用write系统调用。

Futex 是Fast Userspace muTexes的缩写
Futex是一种用户态和内核态混合的同步机制。首先,同步的进程间通过mmap共享一段内存,futex变量就位于这段共享的内存中且操作是原子的,当进程尝试进入互斥区或者退出互斥区的时候,先去查看共享内存中的futex变量,如果没有竞争发生,则只修改futex,而不用再执行系统调用了。当通过访问futex变量告诉进程有竞争发生,则还是得执行系统调用去完成相应的处理(wait 或者 wake up)。简单的说,futex就是通过在用户态的检查,(motivation)如果了解到没有竞争就不用陷入内核了,大大提高了low-contention时候的效率。

通过查阅资料,了解了futex系统调用少的原因,其设计出发点就是为了解决原本IPC通信频繁陷入内核,上下文切换开销太大的缺点,这也说明c++11的mutex底层是依赖于futex实现的,是非常高效的。

播放器

播放器结果

下面的结果是我追踪我的数据包播放器的系统调用情况:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.051993       12998         4           futex
  0.00    0.000000           0         8           read
  0.00    0.000000           0         7           write
  0.00    0.000000           0         8           close
  0.00    0.000000           0        25        21 stat
  0.00    0.000000           0         9           fstat
  0.00    0.000000           0         2           lseek
  0.00    0.000000           0        19           mmap
  0.00    0.000000           0        14           mprotect
  0.00    0.000000           0         1           munmap
  0.00    0.000000           0         3           brk
  0.00    0.000000           0         3           rt_sigaction
  0.00    0.000000           0         1           rt_sigprocmask
  0.00    0.000000           0         1           ioctl
  0.00    0.000000           0         7         7 access
  0.00    0.000000           0         2           clone
  0.00    0.000000           0         1           execve
  0.00    0.000000           0         1           arch_prctl
  0.00    0.000000           0         1           gettid
  0.00    0.000000           0         1           set_tid_address
  0.00    0.000000           0        42        34 openat
  0.00    0.000000           0         1           set_robust_list
  0.00    0.000000           0         1           prlimit64
------ ----------- ----------- --------- --------- ----------------
100.00    0.051993                   162        62 total

播放器分析

可以看到,占用了较多时间的系统调用仍旧为futex,和记录器是差不多的。

结论

从系统调用上来看,无论是最开始担心的互斥量竞争,还是new 和 delete的频繁使用(对应mmap系统调用和brk系统调用),都未消耗过多的时间,可以忽略不计,暂时没有可优化的地方。不过如果想优化的话,可以尝试实现一个内存池降低系统调用,另外,互斥量导致的系统调用虽然在总时间上比较少,但一旦出现竞争,每次耗费的时间都在0.01-0.02秒附近,这是非常高的开销,如何减少互斥锁的使用也应该考虑。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值