技术头条 - 一个快速在微博传播文章的方式     搜索本站
您现在的位置首页 --> 系统运维 --> 进程上下文切换 – 残酷的性能杀手(下)

进程上下文切换 – 残酷的性能杀手(下)

浏览:3929次  出处信息

   几个月一直懒得没动笔写写博客,今天趁着加班等出版本,横下心决定把上次烂尾的文章给收了(上篇:http://www.cppthinker.com/linux/224/context_switch_1/)。

   接上篇,我们已经通过分析内核代码看到pthread_cond_signal和pthread_cond_wait会发生CS(Context Switch),本篇我将从实际测试数据出发,来看CS究竟会对我们的应用程序产生怎样的影响。

   一般我们可以通过工具vmstat, dstat, pidstat来观察CS的切换情况。

   vmstat, dstat只能观察整个系统的切换情况,而pidstat可以更精确地观察某个进程的上下文切换情况。

   这里我用了chaos库中task_service的一个测试用例来说明情况(chaos库是我写得一个高性能并发网络库,而task_service是一个提供了多线程通信的异步消息队列) https://github.com/lyjdamzwf/chaos/blob/master/chaos/task_service/task_service.h

   https://github.com/lyjdamzwf/chaos/blob/master/chaos/task_service/task_service.cpp

   这两个文件中,在post异步消息给task_service_t时,会根据头文件中定义的宏在编译期控制调用pthread_cond_signal还是write(fd),这是典型的生产者消费者模型

   注意,通过系统调用write来通知task_service_t内部的线程会有以下几种可能:

   *) pipe

   *) socketpair

   *) eventfd

   它们都是linux中的多进程/多线程通信的常用手段

   我们直接跑一下chaos/test/task_service 下的用例来分别看下不同机制的结果吧


CS/spost costexec cost
pthread_cond_wat/pthread_cond_signal600k32,235,597 us32,235,078 us
sleep3003,987,928 us3,996,383 us
pipe50011,928,024 us11,928,174 us
socket_pair400016,532,314 us16,532,461 us
eventfd2005,136,712 us5,303,645 us
boost::io_service750k26,355,836 us26,355,708 us

   好,让我们一个一个来解读

   首先,使用了pthread的条件变量的chaos::task_service引起的CS非常之大,效率也是最慢,原因其实上篇已经讲述,不管是pthread_cond_wait还是pthread_cond_signal,都会发生一次CS。

   使用了sleep的chaos::task_service,效率是最高的,主要原因是在于生产者每次投递时不需要系统调用进行notify,且CS也是很小的,但是这种模型在理论上没有其他 wait/notify的模型要来的好,而且CS和整体的效率还和sleep的参数有关

   pipe, socket_pair 和 eventfd 都是基于 write系统调用来notify消费者,eventfd是最新内核提供的机制,几乎感受不到的CS让其效率也遥遥领先其他的通信机制

   值得注意的是boost::io_service,我这里的测试系统是linux,windows上的boost::io_service实现没有测试,但其CS切换如此之高,却整体效率比chaos::task_service使用pthread 条件变量的模型来得快一些,我想应该是由于其内部的队列实现,毕竟目前chaos::task_service的队列只是简单的lock deque。

   基于以上统计,我们可以看出基本是呈现CS越少,整体运行效率越高的趋势

   我们可以得出一个比较浅显的结论是,CS起码会是影响我们程序性能的主要因素之一

   当然,任何时候我都觉得测试数据只是眼前的测试数据,它只能告诉我们什么东西值得我们去注意,而不是什么东西一定是怎样的,至少对于后台服务,CS应该是我们常常需要去考量性能的一个因素

   好了,就到这,希望对大家有帮助 \':)\'

   PS. 加班写文章思绪有些乱,前言不搭后语望包含,赶紧撤了~

建议继续学习:

  1. 深入理解Javascript之执行上下文(Execution Context)    (阅读:17114)
  2. 从Java视角理解CPU上下文切换(Context Switch)    (阅读:5447)
  3. 进程上下文切换 – 残酷的性能杀手(上)    (阅读:3310)
  4. 了解JavaScript的执行上下文    (阅读:3181)
  5. 认识javascript中的作用域和上下文    (阅读:2595)
QQ技术交流群:445447336,欢迎加入!
扫一扫订阅我的微信号:IT技术博客大学习
© 2009 - 2024 by blogread.cn 微博:@IT技术博客大学习

京ICP备15002552号-1