你们中的任何人都有一个经验法则,关于Linux服务器上有多少个上下文切换(每个处理器核心)是正常的吗?
我的大学在这里提出了,他在8核x86_64机器上看到16K.
以下是过去几天来自sarface的一些统计数据……
alt text http://src.autonomy.net.au/imagebin/81895e338fae67d3d205c09db44a81e6-Picture_10.png
要查看流程创建统计信息,这里是同一图表的对数视图……
alt text http://src.autonomy.net.au/imagebin/7481f7e52bead4effc90248fc23c72fe-Picture_11.png
8核心无聊到死…
alt text http://src.autonomy.net.au/imagebin/0e94326652e977fd74edcd840f94200f-Picture_12.png
CS vs IOwait(x10000比例)
alt text http://src.autonomy.net.au/imagebin/a52a2a8a120394849c0da4045933e306-Picture_13.png
如果有人要求,更多无用的信息..
>服务器运行的存储是通过FC的0.5TB SAN
>有8GB的RAM,主要是缓存 – 没有交换.
解决方法
系统调用
系统调用会导致上下文切换本身的性质.当一个进程进行系统调用时,它基本上会告诉内核从它当前的时间点和内存中接管进行该进程无权执行的操作,并在完成时返回到同一位置.
当我们从Linux查看write(2)系统调用的定义时,这变得非常清楚:
NAME write - write to a file descriptor SYNOPSIS #include ssize_t write(int fd,const void *buf,size_t count); DESCRIPTION write() writes up to count bytes from the buffer pointed buf to the file referred to by the file descriptor fd. [..] RETURN VALUE On success,the number of bytes written is returned (zero indicates nothing was written). On error,-1 is returned,and errno is set appropriately. [..]
这基本上告诉内核从进程中接管操作,向上移动到count字节,从* buf指向的内存地址开始到当前进程的文件描述符fd,然后返回到进程并告诉他它是如何进行的.
显示这一点的一个很好的例子是基于Valve Source的游戏的专用游戏服务器,hlds.http://nopaste.narf.at/f1b22dbc9显示由一个没有玩家的游戏服务器的单个实例完成的一秒钟系统调用.这个过程在Xeon X3220(2.4Ghz)上占用大约3%的cpu时间,只是为了让您感觉这是多么昂贵.
多任务
上下文切换的另一个来源可能是不进行系统调用但需要从给定的cpu移出以为其他进程腾出空间的进程.
可视化这个的一个很好的方法是cpuburn. cpuburn本身不做任何系统调用,它只是迭代它自己的内存,所以它不应该导致任何上下文切换.
获取空闲机器,启动vmstat,然后为系统的每个cpu核心运行burnMMX(或cpuburn包中的任何不同测试).到那时你应该有完整的系统利用率,但几乎没有增加任何上下文切换然后尝试启动更多进程.随着流程开始与cpu核心竞争,您将看到上下文切换速率增加.切换量取决于进程/核心比率和内核的多任务分辨率.
进一步阅读
linfo.org对于context switches和system calls有一个很好的写作. Wikipedia有关于系统调用的通用信息和一个很好的链接集合.