读书人

从Java视角理解CPU下上文切换(Context

发布时间: 2012-09-06 10:37:01 作者: rapoo

从Java视角理解CPU上下文切换(Context Switch)
从Java视角理解系统结构连载, 关注我的微博(链接)了解最新动态

在高性能编程时,经常接触到多线程. 起初我们的理解是, 多个线程并行地执行总比单个线程要快, 就像多个人一起干活总比一个人干要快. 然而实际情况是, 多线程之间需要竞争IO设备, 或者竞争锁资源,导致往往执行速度还不如单个线程. 在这里有一个经常提及的概念就是: 上下文切换(Context Switch).

上下文切换的精确定义可以参考: http://www.linfo.org/context_switch.html. 下面做个简单的介绍. 多任务系统往往需要同时执行多道作业.作业数往往大于机器的CPU数, 然而一颗CPU同时只能执行一项任务, 如何让用户感觉这些任务正在同时进行呢? 操作系统的设计者巧妙地利用了时间片轮转的方式, CPU给每个任务都服务一定的时间, 然后把当前任务的状态保存下来, 在加载下一任务的状态后, 继续服务下一任务. 任务的状态保存及再加载, 这段过程就叫做上下文切换. 时间片轮转的方式使多个任务在同一颗CPU上执行变成了可能, 但同时也带来了保存现场和加载现场的直接消耗.
(Note. 更精确地说, 上下文切换会带来直接和间接两种因素影响程序性能的消耗. 直接消耗包括: CPU寄存器需要保存和加载, 系统调度器的代码需要执行, TLB实例需要重新加载, CPU 的pipeline需要刷掉; 间接消耗指的是多核的cache之间得共享数据, 间接消耗对于程序的影响要看线程工作区操作数据的大小).


在linux中可以使用vmstat观察上下文切换的次数. 执行命令如下:


编译后,在我自己的笔记本上( Intel(R) Core(TM) i5 CPU M 460 @ 2.53GHz, 2 core, 3M L3 Cache) 用测试几轮,结果如下:
yubaofu@java$taskset -c 0 perf stat -e cs java -cp . ContextSwitchTestparks: 996667parks: 996658Average time: 1921nsparks: 997488parks: 979789Average time: 1927nsparks: 987008parks: 1000001Average time: 1871ns Performance counter stats for 'java -cp . ContextSwitchTest':         6,102,090 cs                                                                11.402238007 seconds time elapsedyubaofu@java$perf stat -e cs java -cp . ContextSwitchTestparks: 949590parks: 949608Average time: 5680nsparks: 956224parks: 955899Average time: 5581nsparks: 941611parks: 942028Average time: 5578ns Performance counter stats for 'java -cp . ContextSwitchTest':         5,708,444 cs                                                                32.024738227 seconds time elapsed

11 楼 coderplay 2012-04-25 fuyou001 写道绑定到特定的cpu 与不绑定cpu cache-misses相差不大

能告诉我你的CPU型号吗?

读书人网 >编程

热点推荐