内存和处理器的关系亲和性和负载平衡两者之间有什么关系

Linux(170)
操作系统(6)
简单地说,CPU 亲和性(affinity)&就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。Linux 内核进程调度器天生就具有被称为&软 CPU 亲和性(affinity)&的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。
2.6 版本的 Linux 内核还包含了一种机制,它让开发人员可以编程实现&硬 CPU 亲和性(affinity)。这意味着应用程序可以显式地指定进程在哪个(或哪些)处理器上运行。
什么是 Linux 内核硬亲和性(affinity)?
在 Linux 内核中,所有的进程都有一个相关的数据结构,称为&task_struct。这个结构非常重要,原因有很多;其中与 亲和性(affinity)相关度最高的是&cpus_allowed&位掩码。这个位掩码由&n&位组成,与系统中的&n&个逻辑处理器一一对应。
具有 4 个物理 CPU 的系统可以有 4 位。如果这些 CPU 都启用了超线程,那么这个系统就有一个 8 位的位掩码。
如果为给定的进程设置了给定的位,那么这个进程就可以在相关的 CPU 上运行。因此,如果一个进程可以在任何 CPU 上运行,并且能够根据需要在处理器之间进行迁移,那么位掩码就全是 1。实际上,这就是 Linux 中进程的缺省状态。
Linux 内核 API 提供了一些方法,让用户可以修改位掩码或查看当前的位掩码:
sched_set_affinity()&(用来修改位掩码)sched_get_affinity()&(用来查看当前的位掩码)
注意,cpu_affinity&会被传递给子线程,因此应该适当地调用&sched_set_affinity。
为什么应该使用硬亲和性(affinity)?
通常 Linux 内核都可以很好地对进程进行调度,在应该运行的地方运行进程(这就是说,在可用的处理器上运行并获得很好的整体性能)。内核包含了一些用来检测 CPU 之间任务负载迁移的算法,可以启用进程迁移来降低繁忙的处理器的压力。
一般情况下,在应用程序中只需使用缺省的调度器行为。然而,您可能会希望修改这些缺省行为以实现性能的优化。让我们来看一下使用硬亲和性(affinity) 的 3 个原因。
原因 1. 有大量计算要做
基于大量计算的情形通常出现在科学和理论计算中,但是通用领域的计算也可能出现这种情况。一个常见的标志是您发现自己的应用程序要在多处理器的机器上花费大量的计算时间。
原因 2. 您在测试复杂的应用程序
测试复杂软件是我们对内核的亲和性(affinity)技术感兴趣的另外一个原因。考虑一个需要进行线性可伸缩性测试的应用程序。有些产品声明可以在&使用更多硬件&时执行得更好。
我们不用购买多台机器(为每种处理器配置都购买一台机器),而是可以:
购买一台多处理器的机器不断增加分配的处理器测量每秒的事务数评估结果的可伸缩性
如果应用程序随着 CPU 的增加可以线性地伸缩,那么每秒事务数和 CPU 个数之间应该会是线性的关系(例如斜线图 —— 请参阅下一节的内容)。这样建模可以确定应用程序是否可以有效地使用底层硬件。
Amdahl 法则说明这种加速比在现实中可能并不会发生,但是可以非常接近于该值。对于通常情况来说,我们可以推论出每个程序都有一些串行的组件。随着问题集不断变大,串行组件最终会在优化解决方案时间方面达到一个上限。
Amdahl 法则在希望保持高 CPU 缓存命中率时尤其重要。如果一个给定的进程迁移到其他地方去了,那么它就失去了利用 CPU 缓存的优势。实际上,如果正在使用的 CPU 需要为自己缓存一些特殊的数据,那么所有其他 CPU 都会使这些数据在自己的缓存中失效。
因此,如果有多个线程都需要相同的数据,那么将这些线程绑定到一个特定的 CPU 上是非常有意义的,这样就确保它们可以访问相同的缓存数据(或者至少可以提高缓存的命中率)。否则,这些线程可能会在不同的 CPU 上执行,这样会频繁地使其他缓存项失效。
原因 3. 您正在运行时间敏感的、决定性的进程
我们对 CPU 亲和性(affinity)感兴趣的最后一个原因是实时(对时间敏感的)进程。例如,您可能会希望使用硬亲和性(affinity)来指定一个 8 路主机上的某个处理器,而同时允许其他 7 个处理器处理所有普通的系统调度。这种做法确保长时间运行、对时间敏感的应用程序可以得到运行,同时可以允许其他应用程序独占其余的计算资源。
下面的样例应用程序显示了这是如何工作的。
如何利用硬亲和性(affinity)
现在让我们来设计一个程序,它可以让 Linux 系统非常繁忙。可以使用前面介绍的系统调用和另外一些用来说明系统中有多少处理器的 API 来构建这个应用程序。实际上,我们的目标是编写这样一个程序:它可以让系统中的每个处理器都繁忙几秒钟。可以从后面的“下载”一节中&。
清单 1. 让处理器繁忙
/* This method will create threads, then bind each to its own cpu. */
bool do_cpu_stress(int numthreads)
int ret = TRUE;
int created_thread = 0;
/* We need a thread for each cpu we have... */
while ( created_thread & numthreads - 1 )
int mypid = fork();
if (mypid == 0) /* Child process */
printf(&\tCreating Child Thread: #%i\n&, created_thread);
else /* Only parent executes this */
/* Continue looping until we spawned enough threads! */ ;
created_thread++;
/* NOTE: All threads execute code from here down! */
正如您可以看到的一样,这段代码只是通过 fork 调用简单地创建一组线程。每个线程都执行这个方法中后面的代码。现在我们让每个线程都将亲和性(affinity)设置为自己的 CPU。
清单 2. 为每个线程设置 CPU 亲和性(affinity)
/* CPU_ZERO initializes all the bits in the mask to zero. */
CPU_ZERO( &mask );
/* CPU_SET sets only the bit corresponding to cpu. */
CPU_SET( created_thread, &mask );
/* sched_setaffinity returns 0 in success */
if( sched_setaffinity( 0, sizeof(mask), &mask ) == -1 )
printf(&WARNING: Could not set CPU Affinity, continuing...\n&);
如果程序可以执行到这儿,那么我们的线程就已经设置了自己的亲和性(affinity)。调用&sched_setaffinity&会设置由&pid&所引用的进程的 CPU 亲和性(affinity)掩码。如果&pid&为
0,那么就使用当前进程。
亲和性(affinity)掩码是使用在&mask&中存储的位掩码来表示的。最低位对应于系统中的第一个逻辑处理器,而最高位则对应于系统中最后一个逻辑处理器。
每个设置的位都对应一个可以合法调度的 CPU,而未设置的位则对应一个不可调度的 CPU。换而言之,进程都被绑定了,只能在那些对应位被设置了的处理器上运行。通常,掩码中的所有位都被置位了。这些线程的亲和性(affinity)都会传递给从它们派生的子进程中。
注意不应该直接修改位掩码。应该使用下面的宏。虽然在我们的例子中并没有全部使用这些宏,但是在本文中还是详细列出了这些宏,您在自己的程序中可能需要这些宏。
清单 3. 间接修改位掩码的宏
void CPU_ZERO (cpu_set_t *set)
这个宏对 CPU 集 set 进行初始化,将其设置为空集。
void CPU_SET (int cpu, cpu_set_t *set)
这个宏将 cpu 加入 CPU 集 set 中。
void CPU_CLR (int cpu, cpu_set_t *set)
这个宏将 cpu 从 CPU 集 set 中删除。
int CPU_ISSET (int cpu, const cpu_set_t *set)
如果 cpu 是 CPU 集 set 的一员,这个宏就返回一个非零值(true),否则就返回零(false)。
对于本文来说,样例代码会继续让每个线程都执行某些计算量较大的操作。
清单 4. 每个线程都执行一个计算敏感的操作
/* Now we have a single thread bound to each cpu on the system */
int computation_res = do_cpu_expensive_op(41);
sched_getaffinity(0, sizeof(mycpuid), &mycpuid);
if ( check_cpu_expensive_op(computation_res) )
printf(&SUCCESS: Thread completed, and PASSED integrity check!\n&,
ret = TRUE;
printf(&FAILURE: Thread failed integrity check!\n&,
ret = FALSE;
现在您已经了解了在 Linux 2.6 版本的内核中设置 CPU 亲和性(affinity)的基本知识。接下来,我们使用一个&main&程序来封装这些方法,它使用一个用户指定的参数来说明要让多少个 CPU 繁忙。我们可以使用另外一个方法来确定系统中有多少个处理器:
int NUM_PROCS = sysconf(_SC_NPROCESSORS_CONF);
这个方法让程序能够自己确定要让多少个处理器保持繁忙,例如缺省让所有的处理器都处于繁忙状态,并允许用户指定系统中实际处理器范围的一个子集。
运行样例程序
当运行前面介绍的&&时,可以使用很多工具来查看
CPU 是否是繁忙的。如果只是简单地进行测试,可以使用 Linux 命令top。在运行&top&命令时按下 “1” 键,可以看到每个 CPU 执行进程所占用的百分比。
这个样例程序虽然非常简单,但是它却展示了使用 Linux 内核中实现的硬亲和性(affinity)的基本知识。(任何使用这段代码的应用程序都无疑会做一些更有意义的事情。)了解了 CPU 亲和性(affinity)内核 API 的基本知识,您就可以从复杂的应用程序中榨取出最后一点儿性能了。
本博客文章欢迎转载,转载时请注意标明出处。
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:183057次
积分:3088
积分:3088
排名:第11907名
原创:105篇
转载:211篇
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'博客访问: 659820
博文数量: 202
博客积分: 7991
博客等级: 少将
技术积分: 2117
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
假如系统中有俩CPU,俩网卡,默认情况下,中断会在同一个CPU上,比如:# cat /proc/interrupts&&&&&&&&&& CPU0&&& && CPU1114:& &&&&&&&&& 0&&&&&& PCI-MSI-X& eth0-rx122:&& &&&&&&&&& 0&&&&&& PCI-MSI-X& eth0-tx130:&& &&&&&&&&& 0&&&&&& PCI-MSI-X& eth1-rx138:&& &&&&&&&&& 0&&&&&& PCI-MSI-X& eth1-tx……这就会使CPU1处于频繁中断之后成为瓶颈,在这种情况下,可以设置第二块网卡中断的CPU亲和性,使其在CPU1上进行中断触发:(将CPU的掩码写入)# echo 2 & /proc/irq/130/smp_affinity# echo 2 & /proc/irq/138/smp_affinity
阅读(4122) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。可以通过设置isolcpus来设置独占,在机器启动的时候,线程默认不占用该CPU,但通过设置cpu亲和性可以占用该cpu.
2.ubutun设置isolcpus的步骤:
&&&&&&&& 2-1)修改/etc/default/grub文件,在GRUB_CMDLINE_LINUX_DEFAULT变量中添加isolcpus=3,对isolcpus的值如果有多个cpu,用逗号隔开。
&&&&&&&& 2-2)然后保存。执行命令:update-grub。然后程序会将刚修改后的内容写到引导程序要执行的配置文件/boot/grub/grub.cfg中,如下图:
&&&&&&&& 2-3)重启计算机后配置生效。
3.程序可以使用sched_setaffinity函数来设置线程的cpu亲和性,调用方式如下:
bool SetAffinity(int nCpuNo)
CPU_ZERO(&mask);
CPU_SET(nCpuNo, &mask);
if(sched_setaffinity(0, sizeof(mask), &mask) == -1)
&&相关文章推荐
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:113602次
积分:1698
积分:1698
排名:千里之外
原创:63篇
转载:14篇
(1)(1)(1)(1)(1)(4)(1)(1)(1)(7)(1)(1)(16)(23)(1)(4)(1)(5)(1)(3)(1)(2)
(window.slotbydup = window.slotbydup || []).push({
id: '4740881',
container: s,
size: '200,200',
display: 'inlay-fix'博客访问: 17559
博文数量: 1
博客积分: 15
博客等级: 民兵
技术积分: 15
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: LINUX
原文地址: 作者:
通常情况下,在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",那么超线程是打开的。
阅读(12806) | 评论(0) | 转发(0) |
上一篇:没有了
下一篇:没有了
相关热门文章
给主人留下些什么吧!~~
请登录后评论。}

我要回帖

更多关于 两者之间的关系 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信