• Linux -- 进程或线程独占CPU


    如果想让特定进程或线程独占某一或某些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

  • 相关阅读:
    hdu 4739 Zhuge Liang's Mines DFS
    Uva 12304
    三角形的心
    最小路径覆盖的理解
    Codeforces Round #192 (Div. 2)
    Uva 11796 Dog Distance
    laravel框架session使用教程
    php session跨页面传递 session值丢失问题
    PHP 5.4中的traits特性
    PHP5.3 goto操作符介绍
  • 原文地址:https://www.cnblogs.com/tuowang/p/9398837.html
Copyright © 2020-2023  润新知