[zz]4.1.5 进程的处理器亲和性和vCPU的绑定

转载自:http://smilejay.com/2012/08/kvm-vcpu-binding/

通常情况下,在SMP系统中,Linux内核的进程调度器根据自有的调度策略将系统中的一个进程调度到某个CPU上执行。一个进程在前一个执行时间 是在cpuM(M为系统中的某CPU的ID)上运行,而在后一个执行时间是在cpuN(N为系统中另一CPU的ID)上运行。这样的情况在Linux中是 很可能发生的,因为Linux对进程执行的调度采用时间片法则(即进行用完自己的时间片即被暂停执行),而默认情况下,一个普通进程或线程的处理器亲和性 是在所有可用的CPU上,有可能在它们之中的任何一个CPU(包括超线程)上执行。

进程的处理器亲和性(Processor Affinity),即是CPU的绑定设置,是指将进程绑定到特定的一个或多个CPU上去执行,而不允许调度到其他的CPU上。Linux内核对进程的调 度算法也是遵守进程的处理器亲和性设置的。设置进程的处理器亲和性带来的好处是可以减少进程在多个CPU之间交换运行带来的缓存命中失效(cache missing),从该进程运行的角度来看,可能带来一定程度上的性能提升。换个角度来看,对进程亲和性的设置也可能带来一定的问题,如破坏了原有SMP 系统中各个CPU的负载均衡(load balance),这可能会导致整个系统的进程调度变得低效。特别是在多处理器、多核、多线程技术使用的情况下,在NUMA(Non-Uniform Memory Access)[3]结构的系统中,如果不能基于对系统的CPU、内存等有深入的了解,对进程的处理器亲和性进行设置是可能导致系统的整体性能的下降而非提升。

每个vCPU都是宿主机中的一个普通的QEMU线程,可以使用taskset工具对其设置处理器亲和性,使其绑定到某一个或几个固定的CPU上去调 度。尽管Linux内核的进程调度算法已经非常高效了,在多数情况下不需要对进程的调度进行干预,不过,在虚拟化环境中有时却有必要对客户机的QEMU进 程或线程绑定到固定的逻辑CPU上。下面举一个云计算应用中需要绑定vCPU的实例。

作为IAAS(Infrastructure As A Service)类型的云计算提供商的A公司(如Amazon、Google、阿里云、盛大云等),为客户提供一个有2个逻辑CPU计算能力的一个客户 机。要求CPU资源独立被占用,不受宿主机中其他客户机的负载水平的影响。为了满足这个需求,可以分为如下两个步骤来实现。

 

第一步,启动宿主机时隔离出两个逻辑CPU专门供一个客户机使用。在Linux内核启动的命令行加上“isolcpus=”参数,可以实现CPU的 隔离,让系统启动后普通进程默认都不会调度到被隔离的CPU上执行。例如,隔离了cpu2和cpu3的grub的配置文件如下:

title Red Hat Enterprise Linux Server (3.5.0)

root (hd0,0)

kernel /boot/vmlinuz-3.5.0 ro root=UUID=1a65b4bb-cd9b-4bbf-97ff-7e1f7698d3db isolcpus=2,3

initrd /boot/initramfs-3.5.0.img

系统启动后,在宿主机中检查是否隔离成功,命令行如下:

[root@jay-linux ~]# ps -eLo psr | grep 0 | wc -l

106

[root@jay-linux ~]# ps -eLo psr | grep 1 | wc -l

107

[root@jay-linux ~]# ps -eLo psr | grep 2 | wc -l

4

[root@jay-linux ~]# ps -eLo psr | grep 3 | wc -l

4

[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==2) print $0}’

root        10     2    10   2 [migration/2]

root        11     2    11   2 [kworker/2:0]

root        12     2    12   2 [ksoftirqd/2]

root       245     2   245   2 [kworker/2:1]

[root@jay-linux ~]# ps –eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==3) print $0}’

root        13     2    13   3 [migration/3]

root        14     2    14   3 [kworker/3:0]

root        15     2    15   3 [ksoftirqd/3]

root       246     2   246   3 [kworker/3:1]

从上面的命令行输出信息可知,cpu0和cpu1上分别有106和107个线程在运行,而cpu2和cpu3上都分别只有4个线程在运行。而且,根 据输出信息中cpu2和cpu3上运行的线程信息(也包括进程在内),分别有migration进程(用于进程在不同CPU间迁移)、两个kworker 进程(用于处理workqueues)、ksoftirqd进程(用于调度CPU软中断的进程),这些进程都是内核对各个CPU的一些守护进程,而没有其 他的普通进程在cup2和cpu3上运行,说明对其的隔离是生效的。

另外,简单解释一下上面的一些命令行工具及其参数的意义。ps命令显示当前系统的进程信息的状态,它的“-e”参数用于显示所有的进程,“-L”参 数用于将线程(LWP,light-weight process)也显示出来,“-o”参数表示以用户自定义的格式输出(其中“psr”这列表示当前分配给进程运行的处理器编号,“lwp”列表示线程的 ID,“ruser”表示运行进程的用户,“pid”表示进程的ID,“ppid”表示父进程的ID,“args”表示运行的命令及其参数)。结合ps和 awk工具的使用,是为了分别将在处理器cpu2和cpu3上运行的进程打印出来。

第二步,启动一个拥有2个vCPU的客户机并将其vCPU绑定到宿主机中两个CPU上。此操作过程的命令行如下:

#(启动一个客户机)

[root@jay-linux kvm_demo]# qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

VNC server running on ‘::1:5900’

 

#(查看代表vCPU的QEMU线程)

[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep

root      3963     1  3963   0 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963     1  3967   0 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963     1  3968   1 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 –daemonize

 

#(绑定代表整个客户机的QEMU进程,使其运行在cpu2上)

[root@jay-linux ~]# taskset -p 0×4 3963

pid 3963′s current affinity mask: 3

pid 3963′s new affinity mask: 4

#(绑定第一个vCPU的线程,使其运行在cpu2上)

[root@jay-linux ~]# taskset -p 0×4 3967

pid 3967′s current affinity mask: 3

pid 3967′s new affinity mask: 4

#(绑定第二个vCPU的线程,使其运行在cpu3上)

[root@jay-linux ~]# taskset -p 0×8 3968

pid 3968′s current affinity mask: 4

pid 3968′s new affinity mask: 8

 

#(查看QEMU线程的绑定是否生效,如下的第5列为处理器亲和性)

[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | grep qemu | grep -v grep

root      3963     1  3963   2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963     1  3967   2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963     1  3968   3 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 –daemonize

#(执行vCPU的绑定后,查看在cpu2上运行的线程)

[root@jay-linux ~]# ps -eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==2) print $0}’

root        10     2    10   2 [migration/2]

root        11     2    11   2 [kworker/2:0]

root        12     2    12   2 [ksoftirqd/2]

root       245     2   245   2 [kworker/2:1]

root      3963     1  3963   2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

root      3963     1  3967   2 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

#(执行vCPU的绑定后,查看在cpu3上运行的线程)

[root@jay-linux ~]# ps –eLo ruser,pid,ppid,lwp,psr,args | awk ‘{if($5==3) print $0}’

root        13     2    13   3 [migration/3]

root        14     2    14   3 [kworker/3:0]

root        15     2    15   3 [ksoftirqd/3]

root       246     2   246   3 [kworker/3:1]

root      3963     1  3968   3 qemu-system-x86_64 rhel6u3.img -smp 2 -m 512 -daemonize

由上面的命令行及其输出信息可知,CPU绑定之前,代表这个客户机的QEMU进程和代表各个vCPU的QEMU线程分别被调度到cpu0和cpu1 上。使用taskset命令将QEMU进程和第一个vCPU的线程绑定到cpu2,将第二个vCPU线程绑定到cpu3上。绑定之后,即可查看到绑定的结 果是生效的,代表两个vCPU的QEMU线程分别运行在cpu2和cpu3上(即使再过一段时间后,它们也不会被调度到其他CPU上去)。

对taskset命令解释一下,此处使用的语法是:taskset -p [mask] pid 。其中,mask是一个代表了处理器亲和性的掩码数字,转化为二进制表示后,它的值从最低位到最高位分别代表了第一个逻辑CPU到最后一个逻辑CPU,进 程调度器可能将该进程调度到所有标为“1”的位代表的CPU上去运行。根据上面的输出,taskset运行之前,QEMU线程的处理器亲和性mask值是 0×3(其二进制值为:0011),可知其可能会被调度到cpu0和cpu1上运行;而运行“taskset -p 0×4 3967”命令后,提示新的mask值被设为0×4(其二进制值为:0100),所以该进程就只能被调度到cpu2上去运行,即通过taskset工具实 现了vCPU进程绑定到特定的CPU上。

上面命令行中,根据ps命令可以看到QEMU的线程和进程的关系,但如何查看vCPU与QEMU线程之间的关系呢?可以切换 (“Ctrl+Alt+2”快捷键)到QEMU monitor中进行查看,运行“info cpus”命令即可(还记得3.6节中运行过的“info kvm”命令吧),其输出结果如下:

(qemu) info cpus

* CPU #0: pc=0xffffffff810375ab thread_id=3967

CPU #1: pc=0xffffffff812b2594 thread_id=3968

从上面的输出信息可知,客户机中的cpu0对应的线程ID为3967,cpu1对应的线程ID为3968。另外,“CPU #0”前面有一个星号(*),是标识cpu0是BSP(Boot Strap Processor,系统最初启动时在SMP生效前使用的CPU)。

总的来说,在KVM环境中,一般并不推荐手动地人为设置QEMU进程的处理器亲和性来绑定vCPU,但是,在非常了解系统硬件架构的基础上,根据实际应用的需求,是可以将其绑定到特定的CPU上去从而提高客户机中的CPU执行效率或者实现CPU资源独享的隔离性。

转载于:https://www.cnblogs.com/zhangzhang/archive/2013/01/27/2878662.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/494379.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

谷歌无人车十年记:理想背后的骨感现实 | 厚势汽车

来源:The Information编译:厚势摘要:即使是近 10 年后,Waymo 仍远没有实现真正的 L4,即使是在相对简单的郊区环境下。「全自动驾驶的汽车来了!」去年 11 月,Waymo 搞了一个大新闻。公司宣布自己…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 19丨行转列【难度中等】​

【未来的你,会感谢今天努力的你】每日两题,一难一易,每天进步一点点,可能会直接导致一场面试的成功,或工作的轻松搞定,从而升职加薪迎娶白富美,加油小伙伴! 🍅举办场地&a…

自定义控件之瀑布流与水波纹实现

本文主要讲述了利用android自定义控件实现瀑布流与水波纹效果 首先为实现效果,应了解touch事件在android中的传递机制 在执行touch事件时 首先执行dispatchTouchEvent方法,执行事件分发。 再执行onInterceptTouchEvent方法,判断是否中断事件…

医学信息学相关术语、缩语及专业名词

医学信息学相关术语、缩语及专业名词 很棒哦,分享了,需要的可以去瞅瞅http://www.med-informatics.cn/MedInfo_gloss/medinfo_gloss_p1.htm如果你到它的完整上再逛逛,发觉还有很多好资源,譬如:http://www.med-informat…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 19丨最后一个能进入电梯的人【难度中等】​

【未来的你,会感谢今天努力的你】每日两题,一难一易,每天进步一点点,可能会直接导致一场面试的成功,或工作的轻松搞定,从而升职加薪迎娶白富美,加油小伙伴! 🍅举办场地&a…

神经网络并不是尚方宝剑,我们需要正视深度 NLP 模型的泛化问题

来源:AI 科技评论前段时间的文章《顶会见闻系列:ACL 2018,在更具挑战的环境下理解数据表征及方法评价》中,我们介绍了 ACL 大会上展现出的 NLP 领域的最新研究风向和值得关注的新进展。从这些新动向上我们似乎应该对深度学习 NLP …

Android之XML序列化和解析

XML文件是一种常用的文件格式&#xff0c;可以用来存储与传递数据 &#xff0c;本文是XML文件序列化与解析的一个简单示例 写文件到本地&#xff0c;并用XML格式存储 /*** 写xml文件到本地*/private void writeXmlToLocal() {List<Person> personList getPersonList()…

北京智控美信(长春)数据中心应聘总结

时间&#xff1a; 2012年9月12日 公司介绍&#xff1a; IT外包公司&#xff0c;提供咨询——开发——维护的整套服务。涉及金融、石油、电力等行业。 代表性项目&#xff1a; 吉林银行的先进性系统。 简历投递&#xff1a; 发送到邮箱&#xff1a;kd.hrinfohold.com.cn (注明应…

信息技术智库丨月度大考试

【未来的你&#xff0c;会感谢今天努力的你】每日两题&#xff0c;一难一易&#xff0c;每天进步一点点&#xff0c;可能会直接导致一场面试的成功&#xff0c;或工作的轻松搞定&#xff0c;从而升职加薪迎娶白富美&#xff0c;加油小伙伴&#xff01; &#x1f345;举办场地&a…

Android之查看网络图片和网页HTML

网络编程是Android应用中很重要的一部分&#xff0c;本文主要讲述了利用HttpURLConnection获取网络图片和HTML的方法。 获取网络图片 public class MainActivity extends Activity implements OnClickListener {private static final String TAG "MainActivity";p…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 20丨查询球队积分【难度中等】​

【未来的你&#xff0c;会感谢今天努力的你】每日两题&#xff0c;一难一易&#xff0c;每天进步一点点&#xff0c;可能会直接导致一场面试的成功&#xff0c;或工作的轻松搞定&#xff0c;从而升职加薪迎娶白富美&#xff0c;加油小伙伴&#xff01; &#x1f345;举办场地&a…

来博客园开了个博客

平时搜索资料也经常搜到博客园的文章&#xff0c;我一看&#xff0c;支持代码高亮&#xff0c;就注册了&#xff0c;也开了个。 以前辗转好多个博客&#xff0c;都没坚持&#xff0c;后来都废弃了。转载于:https://www.cnblogs.com/dyllen/archive/2013/01/31/2887383.html

智能交通大数据及云应用平台解决方案

来源&#xff1a;网络大数据摘要&#xff1a;随着日益增长的交通“大数据”&#xff0c;给交通管理创新带来的新挑战&#xff0c;以及对交通管理工作提出的新要求&#xff0c;交通信息化建设必然步入云计算智慧应用阶段&#xff0c;利用云计算破解当前诸多交通瓶颈问题。什么是…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 20丨查询结果的质量和占比【难度简单】​

【未来的你&#xff0c;会感谢今天努力的你】每日两题&#xff0c;一难一易&#xff0c;每天进步一点点&#xff0c;可能会直接导致一场面试的成功&#xff0c;或工作的轻松搞定&#xff0c;从而升职加薪迎娶白富美&#xff0c;加油小伙伴&#xff01; &#x1f345;举办场地&a…

Android之网络编程

本文主要包括三方面内容 Httpurlconnection中doGet与doPost方法实现提交数据到服务器HttpClient中doGet与doPost方法实现提交数据到服务器android-async-http开源库方法实现提交数据到服务器 首先是服务器端的实现 public class LoginServlet extends HttpServlet {/*** Th…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 21丨每个帖子的评论数【难度中等】​

【未来的你&#xff0c;会感谢今天努力的你】每日两题&#xff0c;一难一易&#xff0c;每天进步一点点&#xff0c;可能会直接导致一场面试的成功&#xff0c;或工作的轻松搞定&#xff0c;从而升职加薪迎娶白富美&#xff0c;加油小伙伴&#xff01; &#x1f345;举办场地&a…

获取当前程序运行的主机名称

#region 获取主机名称 /// <summary> /// 获取主机名称 返回如 www.baidu.com or www.baidu.com:8080 注意没有 http:// /// </summary> /// <returns></returns> public static string GetHttpHost() …

106项人工智能创新项目名单公布,唱响“智能化”主旋律

来源&#xff1a;专知摘要&#xff1a;9月5日&#xff0c;工信部官网公示了2018年人工智能与实体经济深度融合创新项目名单。9月5日&#xff0c;工信部官网公示了2018年人工智能与实体经济深度融合创新项目名单。据了解&#xff0c;2018年人工智能与实体经济深度融合创新项目名…

利用TabWidget实现底部菜单

TabWidget类似于通话记录的界面&#xff0c;通过切换多个标签从而显示出多个不同内容&#xff0c;能够展示内容丰富的页面信息&#xff0c;而且彼此之间不会干扰&#xff0c;有利于展示。下面&#xff0c;通过一个例子来学习用法 首先用一个类来继承TabActivity 在开发之前&a…

【每日SQL打卡】​​​​​​​​​​​​​​​DAY 21丨报告系统状态的连续日期【难度困难】​

【未来的你&#xff0c;会感谢今天努力的你】每日两题&#xff0c;一难一易&#xff0c;每天进步一点点&#xff0c;可能会直接导致一场面试的成功&#xff0c;或工作的轻松搞定&#xff0c;从而升职加薪迎娶白富美&#xff0c;加油小伙伴&#xff01; &#x1f345;举办场地&a…