linux应用如何进行cpulinux绑定cpu的坏处

在Linux下,有没API可以捕获一个进程在哪个CPU核心上运行?
[问题点数:20分,结帖人Dracula777]
本版专家分:0
结帖率 100%
CSDN今日推荐
本版专家分:7017
本版专家分:0
本版专家分:0
本版专家分:0
匿名用户不能发表回复!
其他相关推荐本文目录 []
添加新评论
友情提醒:填写邮箱是当别人回复你的评论时,会给邮箱发邮件提醒。
Not seeing a ? Go to our FAQ page for more info.博客访问: 1254131
博文数量: 286
博客积分: 3713
博客等级: 少校
技术积分: 2275
注册时间:
http://blog.chinaunix.net/uid/.html
分类: LINUX 08:11:12
原文地址: 作者:
通常情况下,在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
[root@jay-linux ~]# ps -eLo psr | grep 1 | wc -l
[root@jay-linux ~]# ps -eLo psr | grep 2 | wc -l
[root@jay-linux ~]# ps -eLo psr | grep 3 | wc -l
[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资源独享的隔离性。
[] 添加几个关于CPU亲和性的小知识点:
1. 限制CPU亲和性的原因一般有如下3个:
1.1 任务中有大量计算存在;
1.2 测试复杂的应用程序(随着CPU个数的正常,程序的处理能力可以线性地扩展);
1.3 运行时间敏感的进程(实时性要求很高)。
2. 子进程会继承父进程的affinity属性(其实用taskset方式启动一个进程就是一次fork+exec)。
3. 在进程的代码中,使用sched_setaffinity函数可以设置该进程的CPU亲和性。
int sched_setaffinity(pid_t pid, unsigned int len, unsigned long *mask);
int sched_getaffinity(pid_t pid, unsigned int len, unsigned long *mask);
4. 使用Nginx时,其配置文件conf/nginx.conf中支持一个名为worker_cpu_affinity的配置项,也就是说,nginx可以为每个工作进程绑定CPU。
如下配置:
worker_processes 3;
worker_cpu_affinity 00;
这里00是掩码,分别代表第2、3、4颗CPU核心(或超线程)。
重启nginx后,3个工作进程就可以各自用各自的CPU了。
5. 在Windows系统中的“任务管理器”中,也可以对一个进程设置CPU亲和性“set affinity”。
逻辑CPU个数:
逻辑CPU个数是指cat /proc/cpuinfo 所显示的processor的个数
# cat /proc/cpuinfo | grep "processor" | wc -l
物理CPU个数:
物理CPU个数,是指physical id(的值)的数量
# cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l
每个物理CPU中Core的个数:
每个相同的physical id都有其对应的core id。如core id分别为1、2、3、4,则表示是Quad-Core CPU,若core id分别是1、2,则表示是Dual-Core。
# cat /proc/cpuinfo | grep "cpu cores" | wc -l
是否为超线程?
如果有两个逻辑CPU具有相同的"core id",那么超线程是打开的。
每个物理CPU中逻辑CPU(可能是core, threads或both)的个数:
# cat /proc/cpuinfo | grep "siblings"
逻辑cpu既可能是cores的个数,也可能是core的倍数。当它和core的个数相等时,表示每一个core就是一个逻辑CPU,若它时core的2倍时,表示每个core又enable了超线程(Hyper-Thread)。比如:一个双核的启用了超线程的物理cpu,其core id分别为1、2,但是sibling是4,也就是如果有两个逻辑CPU具有相同的"core id",那么超线程是打开的。
阅读(20540) | 评论(3) | 转发(0) |
给主人留下些什么吧!~~
这个可以有
大虾小鱼,IT知识与技术的共享者!
请登录后评论。多线程程序运行在多核CPU上,如果不进行核心绑定,经检测,默认是使用所有核心来运行程序的。即使单线程程序,运行过程中也会切换CPU核心。
CPU核心绑定的方式
绑定CPU核心,即设置CPU亲和力或者设置处理器关系。在网上查了一些资料,比较常见的绑定CPU核心的方法主要是这两个:
命令/脚本实现方式:taskset
程序实现方式:
进程:sched_setaffinity
线程:pthread_setaffinity_np
1. taskset实现
简介:linux提供的一个命令,它可以让某个进程运行在某个/某些CPU核心上
使用情形:taskset设置CPU亲和力也分两种情况
[1] 运行中设置:即知道了进程pid再进行绑定操作
这种方法的最大弊端就是不具有实时性
[2] 启动时设置:即在程序开始执行时就进行绑定操作
这种方法对于适用于实时的性能测试
[1] 显示进程在用CPU
taskset -p pid
taskset -p 3652
pid 3652’s current affinity mask: f
f = 1111的bitmask,表示进程3652在用的CPU,即四个核心都会使用
[2] 进程与特定CPU核心绑定
taskset -pc cpu_id pid
taskset -pc 3 2499
pid 2499’s current affinity list: 0-3
pid 2499’s new affinity list: 3
表示程序绑定在第4个核心运行(从0开始计数)
[3] 进程启动时指定CPU
taskset -c 1 vlc
表示启动vlc并绑定在第2个核心运行,程序启动后查看各个线程的核心占用如下图(P表示正在使用的核心)
taskset -c 0,5,7,9-11 vlc
表示启动vlc并绑定在0,5,7,9-11范围的核心运行
taskset -pc 0,3,7-11 700
表示将进程700与特定CPU核心list绑定
2. 程序实现
进程绑定到CPU
Linux提供一个接口,可以将进程绑定到特定的CPU:
#include &sched.h&
int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
pid:进程的id号,如果pid为0,则表示本进程
cpusetsize:mask的大小
mask:运行进程的CPU,可以通过以下函数操作mask
#define CPU_SET(cpu, cpusetp)
#define CPU_CLR(cpu, cpusetp)
#define CPU_ISSET(cpu, cpusetp) //判断cpu
#define CPU_ZERO(cpusetp)
//初始化为0
线程绑定到CPU
Linux提供一个接口,可以将线程绑定到特定的CPU
该接口与进程绑定到CPU的接口的使用方法基本一致
注:当进程绑定到特定的CPU之后,线程还是可以绑定到其他的CPU的,没有冲突。
#include &pthread.h&
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);
程序实现使用示例可参考:
Acknowledgements:
linux绑定进程到指定cpu
方法之一:
top -p `pidof 进程名称`
方法之二:
-p `ps h -o pid -C 进程名称`
如果还要查看此进程下的各线程,可用如下:
linux应用如何进行cpu绑定
所谓cpu绑定,其实就是对进程或线程设置相应的cpu亲和力(affinity),确保进程或线程只会在设置了相应标志位的cpu上运行,进而提高应用对cpu的使用效率。如果应用可以在多个cpu上运行,操作...
linux下进程绑定cpu情况查看
1.pidstat命令
查看进程使用cpu情况,如果绑定了多个cpu会都显示出来
pidstat -p `pidof 进程名` -t 1
(2)按f键可以选择下面配置选项...
Linux下进程绑定多CPU运行
在服务器上,我们经常会有多个CPU的情况,而此时如果把进程都绑定在一个CPU上,那么对资源太多浪费了,下面的代码就实现了如何将程序绑定在不同的cpu上。传入参数代表绑定第几个cpu(从0开始计算)
如何将一个进程(线程)绑定到一个固定的CPU核上?
google一圈,能够实现的方式有两种:第一种:linux的shell命令行方式,命令名字为taskset。第二种就是代码实现级别的了,pthread_setaffinity_np和sched_set...
考虑到大量并发,很多线程频繁调度的场景下,linux系统的性能会下降,那么关键的线程得不到及时调度,就会产生问题。
为了保证关键的线程能够及时调度,可以使用把线程、进程,绑定到指定的CPU核上面,避免...
在测试斗地主程序的时候,发现单核cpu的运行时间总比多核cpu运行时间块,用taskset命令一看,果然是一个进程运行在两个cpu上。
Score of team 1 is : -1154...
By:Ailson Jack
个人博客:www.only2fire.com
本文在我博客的地址是:http://w...
如果你觉得比内核的进程调度器更了解你的进程,不想过多的占用CPU0,更高的缓存命中,那么可以设置进程运行在某个或某些CPU上。
redis是单进程模型,为了充分利用多核服务器性能,可以指定不同...
linux cpu绑定
简要介绍自己在学习linuxcpu绑定的一些内容,部分内容总结于互联网
没有更多推荐了,
(window.slotbydup=window.slotbydup || []).push({
id: "5865577",
container: s,
size: "300,250",
display: "inlay-fix"linux获取cpu使用率_百度经验
&&&&&&&&&台式机linux获取cpu使用率听语音1234567
百度经验:jingyan.baidu.com&&&&& Windows查看CPU使用率很简单,我们通过任务管理器就能看到。那么对于linux来说,怎么查看获取CPU使用率呢?咗嚛本经验以Centos系统为例百度经验:jingyan.baidu.comCentos百度经验:jingyan.baidu.com1实时CPU使用率&& 类似任务管理器实时系统信息可以通过top命令查看。显示的信息四个参数分别是:用户的模式(user)、低优先级的用户模式(nice)、系统内核模式(system)以及系统空闲的处理器时间(idle)2查看CPU处理器使用率对于CPU使用率一般都是通过CPU使用情况,查看/proc/stat&cpu状态文件3平均CPU使用率对于一般某时间段CPU的使用率来说,可以通过查看/pRoc/loadavg&文件信息4第三方监控软件查看网上有很多网管,监控软件安装配置好之后。可以通过网页管理查看CPU等硬件情况和CPU使用率,负载等参数END百度经验:jingyan.baidu.com1内存使用率&查看&/proc/meminfo查看内存详细信息,也可以通过free&命令查看2网络利用率&通过查看文件/proc/net/dev&可以了解,centos系统的网络使用情况跟windows的网络情况类似END百度经验:jingyan.baidu.com如果是查看系统负载的话是需要通过,CPU使用率,内存使用率,网络负载,硬盘容量等等来综合计算出来的。如果对于linux不是特别了解,或者想一次获取比较全面,可以通过编写脚本或者相关的监控工具。经验内容仅供参考,如果您需解决具体问题(尤其法律、医学等领域),建议您详细咨询相关领域专业人士。作者声明:本篇经验系本人依照真实经历原创,未经许可,谢绝转载。投票(20)已投票(20)有得(0)我有疑问(0)◆◆说说为什么给这篇经验投票吧!我为什么投票...你还可以输入500字◆◆只有签约作者及以上等级才可发有得&你还可以输入1000字◆◆如对这篇经验有疑问,可反馈给作者,经验作者会尽力为您解决!你还可以输入500字相关经验027712热门杂志第1期你不知道的iPad技巧3833次分享第1期win7电脑那些事6674次分享第2期新人玩转百度经验1425次分享第1期Win8.1实用小技巧2670次分享第1期小白装大神1963次分享◆请扫描分享到朋友圈

我要回帖

更多关于 linux绑定cpu失败 的文章

 

随机推荐