如果想让特定进程或线程独占某一或某些CPU,我们需要做三件事.

一,隔离CPU,避免其它线程run在被隔离的CPU上.

二,绑定所有的interrupts到非隔离的CPU上,避免被隔离的CPU收到interrupt.

三,据你希望地,把特定的线程绑定到某一被隔离的CPU上.

1.CPU isolation

如果想让特定进程或线程独占某一或某些CPU,我们需要避免其它进程运行在该CPU上.因此,我们所做的第一步是CPU隔离.

CPU隔离的方法:

修改Linux内核的启动参数isolcpus. isolcpus将从线程调度器中移除选定的CPU,这些被移除的CPU称为"isolated" CPU. 若想要在被隔离的CPU上run进程,必须调用CPU亲和度相关的syscalls.

具体的修改方法是在/ boot/grub/grub.conf的kernel列最末尾加上isolcpus=x,y,… (代表将CPUx CPUy隔离)

隔离CPU还有一些其它方法,但是这种方法是首选方法,也是redhat的推荐方法.

另一方法利用了CPU亲和性的继承性,即子进程会继承父进程的CPU亲和性.由于所有进程都是init的子进程,我们可以设置init的CPU亲和性,这样一来,所有的进程都具有了与init相同的CPU亲和性.然后我们可以更改我们需要的进程的CPU亲和性来达到独占.

2.Interrupt request(IRQ)

被隔离的CPU虽然没有线程run在上面,但是仍会收到interrupt.

Interrupt request是硬件级别的服务请求.详情见附录,此处不表.我们需要知道的是IRQ有一个亲和度属性smp_affinity. smp_affinity决定允许哪些CPU核心处理IRQ.

在redhat(其它发行版未知)中,某一特定IRQ的亲和度值储存在/proc/irq/IRP_NUMBER/smp_affinity文件中.此文件仅ROOT用户可见.储存的值是一个十六进制位掩码(hexadecimal bit-mask),代表着系统的所有CPU核心.

命令cat /proc/interrupts可以看到所有设备的interrupts信息,第一列即为IRP_NUMBER.

命令cat /proc/irq/32/smp_affinity可以看到IRQ号为32的亲和度.默认值为f,代表这个IRP能被所有CPU接受处理.

命令echo 1 >/proc/irq/32/smp_affinity把IRQ号为32的亲和度值设为1,代表这个IRP仅能被CPU0接受处理

照此,我们可以据要求任意绑定IRQ到CPU

虽然我们已经做了很大努力,但是仍有一部分中断没有被绑定,例如: Single function call interrupts, Local timer interrupts等等

3.绑定进程到CPU

在以上两步,我们摒除了一部分外界的干扰.最后一步,我们要绑定进程到隔离的CPU上.

首先我们要了解CPU亲和性这个概念.

CPU亲和性就是进程在某个给定的CPU上尽量长时间的运行而不被迁移到其它处理器的倾向性.Linux内核进程调度器天生就具有”软CPU亲和性”,这意味着进程通常不会在处理器之间频繁迁移.

2.6+的Linux内核还包含一种机制.它让开发人员可以编程实现”硬CPU亲和性”.这意味着应用程序可以显示地指定在哪个处理器上运行.

我们所说的绑定进程到CPU就是实现硬CPU亲和性.

代码级别的亲和度设定:

int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);

设定某个进程的CPU亲和度

例码见: http://man7.org/linux/man-pages/man2/sched_setaffinity.2.html

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);

设定某个线程的CPU亲和度

例码见: http://man7.org/linux/man-pages/man3/pthread_setaffinity_np.3.html

以上两者都使用到

CPU宏:

http://man7.org/linux/man-pages/man3/CPU_SET.3.html

void CPU_ZERO(cpu_set_t *set)   //初始化CPU集
void CPU_SET(int cpu,cpu_set_t *set) //向CPU集中添加某个CPU
void CPU_CLR(int cpu,cpu_set_t *set) //从CPU集中移除某个CPU
int CPU_ISSET(int cou,cpu_set_t *set) //检查CPU集中是否存在某个CPU
int CPU_COUNT(cpu_set_t *set) //返回CPU集中CPU的个数
使用taskset指定CPU亲和性:

运行时指定:

命令taskset –c 0,2,3 simulotion.x 代表在CPU0,CPU2,CPU3上运行名为simulation.x的程序

运行后指定:

命令 taskset –p –c 0,2 7013 代表绑定pid为7013的进程到CPU0,CPU2上

Numatcl程序也有类似taskset的功能,此处不表

附录:

1.https://stackoverflow.com/questions/13583146/whole-one-core-dedicated-to-single-process

2.CPU isolation:
https://access.redhat.com/solutions/15482

3.IRQ: https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Performance_Tuning_Guide/s-cpu-irq.html

4.Processor Affinity Bitmask
https://www.intervalzero.com/library/RTX/WebHelp/Content/PROJECTS/Application Development/UsingFunctionality/Specifying_a_Processor_Affinity_Bitmask.htm

这是一个32位的二进制串.最低位代表CPU0,最高位代表CPU31(如果有的话)

5.taskset:
http://www.glennklockwood.com/hpc-howtos/process-affinity.html#2-2-round-robin-scheduling

Linux -- 进程或线程独占CPU的更多相关文章

  1. linux进程、线程与cpu的亲和性(affinity)

    参考:http://www.cnblogs.com/wenqiang/p/6049978.html 最近的工作中对性能的要求比较高,下面简单做一下总结: 一.什么是cpu亲和性(affinity) C ...

  2. Linux进程或线程绑定到CPU

    Linux进程或线程绑定到CPU 为了让程序拥有更好的性能,有时候需要将进程或线程绑定到特定的CPU,这样可以减少调度的开销和保护关键进程或线程. 进程绑定到CPU Linux提供一个接口,可以将进程 ...

  3. Linux 进程、线程运行在指定CPU核上

    /******************************************************************************** * Linux 进程.线程运行在指定 ...

  4. Linux进程和线程的比較

    进程与线程 參考:http://www.cnblogs.com/blueclue/archive/2010/07/16/1778855.html 首先比較Linux进程和线程的创建的差别,以此展开: ...

  5. Linux 进程一直占用单核CPU分析

    pidstat 1信息

  6. linux --> 进程和线程

    进程和线程 进程(process)和线程(thread)是操作系统的基本概念,下面用一个类比,来解释它们. 1. 计算机的核心是CPU,它承担了所有的计算任务.它就像一座工厂,时刻在运行. 2. 假定 ...

  7. Linux进程与线程的区别

    进程与线程的区别,早已经成为了经典问题.自线程概念诞生起,关于这个问题的讨论就没有停止过.无论是初级程序员,还是资深专家,都应该考虑过这个问题,只是层次角度不同罢了.一般程序员而言,搞清楚二者的概念, ...

  8. 操作系统:Linux进程与线程

    这里是一部分内容,还会做修改. 一:目的及内容 学习fork(),exec,pthread库函数的使用,阅读源码,分析fork,exec,pthread_create函数的机理 代码实现: 进程A创建 ...

  9. 获取Linux进程运行在哪个CPU内核上面的方法

    首先,当某些时候,在一段程序或者借助第三方软件进行程序协助的时候,在性能的优化,以及程序bug的排除上面,可能会想知道该程序执行的进程被调度到了哪一个CPU内核进行工作,从而可以推断是否是受限于硬件还 ...

随机推荐

  1. C++——数组形参退化为指针

    数组做形参退化为指针 如果数组作为函数参数,则数组形参会退化为指针,以下代码在编译器看来是等价的 ]); ]); void fun3(int a[]); void fun4(int *a); #inc ...

  2. [唐胡璐]Selenium技巧- Prop.Properties配置测试应用的环境和其他配置项

     prop.propertiesfile contains important info that needs to be changed before the test is run, such a ...

  3. 前端知识体系:JavaScript基础-原型和原型链-new一个对象的详细过程,手动实现一个 new操作符

    可以描述 new一个对象的详细过程,手动实现一个 new操作符 1. new 一个对象的详细过程:(原文地址) 首先我们看下new Person输出什么? var Person = function( ...

  4. 利用python pika库实现rabbitmq客户端

    pika 实现consumer import functools import logging import pika LOG_FORMAT = ('%(levelname) -10s %(ascti ...

  5. BZOJ 4013/Luogu P3240 [HNOI2015] 实验比较 (树形DP)

    题目传送门 分析 放一个dalao博客: xyz32768 的博客,看完再回来看本蒟蒻的口胡吧(其实嘛-不回来也行) 精髓是合并的方案数的计算,至于为什么是Ci−1j−1\large C_{i-1}^ ...

  6. WCF学习笔记二

    客户端调用WCF服务出现以下错误: “/”应用程序中的服务器错误. 远程服务器返回错误: (415) Unsupported Media Type. 说明: 执行当前 Web 请求期间,出现未经处理的 ...

  7. 7、组件注册-@Conditional-按照条件注册bean

    7.组件注册-@Conditional-按照条件注册bean @Conditional 按照一定的条件进行判断,满足条件给容器注入bean 按照条件进行动态装配. Spring 4 开始提供的一个注解 ...

  8. HDU 6154 - CaoHaha's staff | 2017 中国大学生程序设计竞赛 - 网络选拔赛

    /* HDU 6154 - CaoHaha's staff [ 构造,贪心 ] | 2017 中国大学生程序设计竞赛 - 网络选拔赛 题意: 整点图,每条线只能连每个方格的边或者对角线 问面积大于n的 ...

  9. 使用Django 测试客户端一起测试视图,模板和URL

    Django 测试客户端 self.client.get(url)  测试客户端是Django中TestCase类的一个属性名. 至此已经在网站中可以创建一个清单了. 那么,现在是可以在unit te ...

  10. Matlab step方法

    在Matlab中我们经常能看到Java的影子,即面向对象编程(Object Oriented Programming,OOP). 以Turbo编码为例: hTEnc = comm.TurboEncod ...