精华内容
下载资源
问答
  • cpu亲和性绑定
    2021-03-13 11:36:50

    将进程与cpu绑定,最直观的好处就是减少cpu之间的cache同步和切换,提高了cpu cache的命中率,提高代码的效率。

    从cpu架构上,NUMA拥有独立的本地内存,节点之间可以通过互换模块做连接和信息交互,因此每个CPU可以访问整个系统的内存,但是访问远地内存访问效率大大降低,绑定cpu操作对此类系统运行速度会有较大提升,UMA架构下,多cpu通过系统总线访问存储模块。不难看出,NUMA使用cpu绑定时,每个核心可以更专注地处理一件事情,资源体系被充分使用,减少了同步的损耗。

    简单地说,CPU 亲和性(affinity)就是进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性。

    软亲和性(affinity): 就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器,Linux 内核进程调度器天生就具有被称为 软 CPU 亲和性(affinity) 的特性,这意味着进程通常不会在处理器之间频繁迁移。这种状态正是我们希望的,因为进程迁移的频率小就意味着产生的负载小。

    2.6 版本的 Linux 内核还包含了一种机制,它让开发人员可以编程实现硬 CPU 亲和性(affinity)。这意味着应用程序可以显式地指定进程在哪个(或哪些)处理器上运行。

    硬亲和性(affinity):简单来说就是利用linux内核提供给用户的API,强行将进程或者线程绑定到某一个指定的cpu核运行。

    在 Linux 内核中,所有的进程都有一个相关的数据结构,称为 task_struct 。这个结构非常重要,原因有很多;其中与 亲和性(affinity)相关度最高的是cpus_allowed 位掩码。这个位掩码由n位组成,与系统中的n个逻辑处理器一一对应。 具有 4 个物理 CPU 的系统可以有 4 位。如果这些 CPU 都启用了超线程,那么这个系统就有一个 8 位的位掩码。

    如果为给定的进程设置了给定的位,那么这个进程就可以在相关的 CPU 上运行。因此,如果一个进程可以在任何 CPU 上运行,并且能够根据需要在处理器之间进行迁移,那么位掩码就全是 1。实际上,这就是 Linux 中进程的缺省状态。

    一般情况下,在应用程序中只需使用缺省的调度器行为。然而,您可能会希望修改这些缺省行为以实现性能的优化。让我们来看一下使用硬亲和性(affinity) 的 3 个原因。

    原因 1. 有大量计算要做

    基于大量计算的情形通常出现在科学和理论计算中,但是通用领域的计算也可能出现这种情况。一个常见的标志是您发现自己的应用程序要在多处理器的机器上花费大量的计算时间。

    原因 2. 提高Cache命中率

    在多核运行的机器上,每个CPU都有自己的缓存,缓存着进程使用的信息,而进程可能会被OS调度到其他CPU上,如此一来CPU Cache命中率就低了。当绑定CPU后,程序就会一直在指定的cpu跑,不会由OS调度到其他CPU上,提高CPU Cache命中率。

    原因 3. 正在运行时间敏感的、决定性的进程

    我们对 CPU 亲和性(affinity)感兴趣的最后一个原因是实时(对时间敏感的)进程。例如,您可能会希望使用硬亲和性(affinity)来指定一个 8 路主机上的某个处理器,而同时允许其他 7 个处理器处理所有普通的系统调度。这种做法确保长时间运行、对时间敏感的应用程序可以得到运行,同时可以允许其他应用程序独占其余的计算资源。

    进程设置:

    1 cpu_set_t mask;2 /*初始化set集,将set设置为空*/

    3 CPU_ZERO(&mask);4 /*依次将0、1号cpu加入到集合*/

    5 CPU_SET(0, &mask);6 CPU_SET(1, &mask);7 /*将当前进程绑定到cpu*/

    8 sched_setaffinity(0, sizeof(mask), &mask);

    线程设置:

    1 cpu_set_t mask;2 /*初始化set集,将set设置为空*/

    3 CPU_ZERO(&mask);4 /*依次将0、1号cpu加入到集合*/

    5 CPU_SET(0, &mask);6 CPU_SET(1, &mask);7 /*将当前线程程绑定到cpu*/

    8 pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask);

    节选自:

    shell下也可以指定用哪个cpu。这对于作测试很方便。

    更多相关内容
  • Windows下动态绑定进程的CPU亲和性的实例,内附实例,可以直接运行查看结果。在Win10系统中亲测有效。
  • cpu亲和性

    2021-01-14 18:31:46
    如果设置了CPU亲和性,一个进程绑定了CPU之后,那么缓存的命中率就能保持在一个较高的水平,从而提高程序性能,这就是为什么要设置CPU亲和性的原因。另一个好处是提高特定进程调度的优先级,比如

    1. 概述

    CPU亲和性,是指进程在指定的CPU长时间运行,而尽量不向其他CPU迁移。

    在多核CPU的机器上,每个CPU都有自己的缓存,如果进程不显式的绑定CPU,那么有可能在操作系统的调度下,在不同的CPU之间切换,那么原先CPU上的缓存数据就没什么用了,新CPU上的缓存又没有之前的数据,这就造成了缓存命中率降低。如果设置了CPU亲和性,一个进程绑定了CPU之后,那么缓存的命中率就能保持在一个较高的水平,从而提高程序性能,这就是为什么要设置CPU亲和性的原因。另一个好处是提高特定进程调度的优先级,比如一个对实时性要求高的进程做绑定,一方面可以保持它的实时性,另一方面也避免它去干扰其他进程。

    2. 相关命令

    如下命令可以查看某个进程(线程)运行在哪个CPU上

    [root@localhost build]#  ps -eo pid,args,psr | grep ssh
      827 /usr/sbin/sshd -D             1
    11436 sshd: root@pts/1              3
    11839 grep --color=auto ssh         2
    17761 sshd: root@pts/0              3
    [root@localhost build]# pstree -p 827
    sshd(827)─┬─sshd(11436)───bash(11441)───pstree(11906)
              └─sshd(17761)───bash(17767)───mysql(23070)
    [root@localhost build]# ps -To 'pid,lwp,psr,cmd' -p 17761
      PID   LWP PSR CMD
    17761 17761   3 sshd: root@pts/0

     

    超线程技术(Hyper-Threading), 把两个逻辑内核(CPU core)模拟成两个物理芯片,让单个处理器都能使用线程级并行计算,常说的的双核四线程/四核八线程指的就是支持超线程技术的CPU.[1] 要注意,超线程技术是通过延迟隐藏的方法,提高了处理器的性能,本质上,就是多个线程共享一个处理单元。因此,采用超线程技术所获得的性能并不是真正意义上的并行。[2]

    关联命令,taskset

    如下操作可以更改进程对应的CPU

    [root@localhost build]# ps -eo pid,args,psr | grep top
    12383 top                           3
    12387 grep --color=auto top         0
    [root@localhost build]# taskset -cp 2 12383
    pid 12383's current affinity list: 0-3
    pid 12383's new affinity list: 2
    [root@localhost build]# ps -eo pid,args,psr | grep top
    12383 top                           2
    12415 grep --color=auto top         3
    

    主要参数有两个,更多信息可以查看man手册

     -p, --pid
                  操作已存在的PID,而不是加载一个新的程序
     -c, --cpu-list
                  声明CPU的亲和力使用数字表示而不是用位掩码表示. 例如 0,5,7,9-11.

     

    3. 掩码

    下面这一段摘自taskset的man手册,主要讲述CPU亲和性中掩码的作用。

    简而言之就是,

    CPU关联用位掩码表示,最低阶位对应第一个逻辑CPU,最高阶位对应最后一个逻辑CPU。如果给出了一个无效的掩码,则返回一个错误。

    用掩码也可以指定一对多的关系,比如 0x00000003就是绑定0号和1号CPU。.

    taskset is used to set or retrieve the CPU affinity of a running process given its PID or to launch a new COMMAND with a given CPU affinity. CPU affinity is a scheduler property that "bonds" a process to a given set of CPUs on the system. The Linux

    scheduler will honor the given CPU affinity and the process will not run on any other CPUs. Note that the Linux scheduler also supports natural CPU affinity: the scheduler attempts to keep processes on the same CPU as long as practical for performance

    reasons. Therefore, forcing a specific CPU affinity is useful only in certain applications.

     

    The CPU affinity is represented as a bitmask, with the lowest order bit corresponding to the first logical CPU and the highest order bit corresponding to the last logical CPU. Not all CPUs may exist on a given system but a mask may specify more CPUs than

    are present. A retrieved mask will reflect only the bits that correspond to CPUs physically on the system. If an invalid mask is given (i.e., one that corresponds to no valid CPUs on the current system) an error is returned. The masks are typically

    given in hexadecimal. For example,

     

    0x00000001

    is processor #0

     

    0x00000003

    is processors #0 and #1

     

    0xFFFFFFFF

    is all processors (#0 through #31).

     

    When taskset returns, it is guaranteed that the given program has been scheduled to a legal CPU

     

    4. 编程实例

    主要有两个函数API,一个设置,一个获取

    • sched_set_affinity() (用来修改位掩码)
    • sched_get_affinity() (用来查看当前的位掩码)

    一个关键数据结构

    • task_struct

    修改掩码的宏

    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)。
    #define _GNU_SOURCE
    #include <sched.h>
    #include <stdio.h>
    #include <stdlib.h> /* exit */
    #include <unistd.h> /* sysconf */
    
    int main(void) {
        int i, nrcpus;
        cpu_set_t mask;
        unsigned long bitmask = 0;
    
        // 把0号和1号1CPU加入到mask中
        CPU_ZERO(&mask);
        CPU_SET(0, &mask);
        CPU_SET(1, &mask);
        // 设置CPU亲和性
        if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
            perror("sched_setaffinity");
            exit(EXIT_FAILURE);
        }
    
        // 获取CPU情和性
        CPU_ZERO(&mask);
        if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1) {
            perror("sched_getaffinity");
            exit(EXIT_FAILURE);
        }
    
        // 获取逻辑CPU数量
        nrcpus = sysconf(_SC_NPROCESSORS_CONF);
        for (i = 0; i < nrcpus; i++) {
            if (CPU_ISSET(i, &mask)) {
                bitmask |= (unsigned long)0x01 << i;
                printf("processor #%d is set\n", i);
            }
        }
    
        printf("bitmask = %#lx\n", bitmask);
    
        exit(EXIT_SUCCESS);
    }

     

    outputs

    [root@localhost cpu]# gcc affinity.c -o affinity
    [root@localhost cpu]# ./affinity 
    processor #0 is set
    processor #1 is set
    bitmask = 0x3

     

    5. 使用场景

    • 需要处理大量计算的任务
    • 测试复杂应用的测试任务
    • 重要、敏感、实时性的任务

     

    参考:

    [0] https://zhuanlan.zhihu.com/p/259217757

    [1] https://www.cnblogs.com/LubinLew/p/cpu_affinity.html

    [2] https://baike.baidu.com/item/%E8%B6%85%E7%BA%BF%E7%A8%8B/86034?fromtitle=%E8%B6%85%E7%BA%BF%E7%A8%8B%E6%8A%80%E6%9C%AF&fromid=276864&fr=aladdin

    [3] https://www.ibm.com/developerworks/cn/linux/l-affinity.html

     

    展开全文
  • CPU亲和性设置

    2015-12-03 23:21:04
    【转载】C++关于多线程的CPU亲和性设置
  • 基于CPU亲和性的工业软件实时性研究.pdf
  • 易语言设置cpu亲和性

    2013-06-25 22:24:04
    设置cpu 亲和性的 易语言源代码 我的cpu是 4核8线程cpu编号0-7 -2 在任务管理器设置相关性里面 就会显示6号cpu 如果减去1 那就是7号cpu NUMBER_OF_PROCESSORS 环境变量是显示你多少核心数
  • 获取多核CPU使用率,设置CPU亲和性,设置并发线程数和优先级,绑定线程在特点CPU上运行,并测试
  • CPU亲和性cpu亲和性,通俗来讲,就是程序长时间固定运行在特定cpu上的倾向性,所以也作cpu pinning,即程序钉在cpu上的特性;cpu亲和性在许多特定场合使用会收到意想不到的性能提升效果,一般来说,针对以下几种场景...

    CPU亲和性

    cpu亲和性,通俗来讲,就是程序长时间固定运行在特定cpu上的倾向性,所以也作cpu pinning,即程序钉在cpu上的特性;cpu亲和性在许多特定场合使用会收到意想不到的性能提升效果,一般来说,针对以下几种场景的程序,应该使用cpu亲和性把程序固定在特定cpu上运行

    计算密集型

    诸如编译大型程序(例如内核)、进行科学计算等cpu密集型任务,这类任务通常要运行比较长的时间,且cpu占用都会很高,将程序钉在特定的cpu上运行,尽可能地减少进程切换,使得cpu资源能够最大化地用于计算

    业务敏感型

    业务敏感主要是指诸如数据库和前端http网关这类应用,此类进程通常对延时敏感,而影响延时的因素,除了网络延时外,在处理请求的速度上也有更高的要求,及时响应并处理完请求,就能更好地提高并发能力,另外,某些特定的应用可能对cpu亲和性做了特殊优化,也能够更好地提高性能

    如何使用CPU亲和性

    cpu亲和性是要将程序钉在指定的cpu core上运行,不希望该程序发生迁移,这也就是程序独占cpu资源,需要做到以下两点:

    1、进程绑定到指定的cpu

    2、其他进程不会被调度到这些cpu

    要实现1中的进程绑定到指定的cpu,普遍有4种方法:

    1、cgroup

    2、taskset

    3、numactl

    4、systemd cpuaffinity

    这些方法在之前的调优系统篇已经作了叙述,这里就numactl和systemctl cpuaffinity进行深入分析

    numactl

    numactl的使用基于服务器的numa架构,关于numa架构,网上有非常多的资料可以参考,弄懂numa架构之后,确认服务器的numa架构,就可以使用numactl提供的绑定功能,将特定的服务绑定到指定的cpu上面运行了;numactl实现的绑定是非常可靠的,一旦绑定了进程到特定cpu,该进程就不会被调度到其他的cpu,但是在使用numactl命令的时候,发现一个问题

    首先,为了最大化使用cpu,我在/etc/default/grub文件中编辑这一行:

    1GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet rd.driver.blacklist=nouveau nouveau.modeset=0 net.ifnames=0 isolcpu=8-55"

    即我希望将8-55号cpu从系统程序调度器中去除,这样系统就不会将其他任务调度到这些cpu上面,然后使用numactl启动服务,启动方法就是编辑服务对应的systemctl服务文件,在启动行里加入需要的命令和参数,例如:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27[tanweijie@ceph-c204 ~]$ systemctl cat ceph-osd@1.service

    # /etc/systemd/system/ceph-osd@1.service

    [Unit]

    Description=Ceph object storage daemon osd.1

    After=network-online.target local-fs.target time-sync.target ceph-mon.target

    Wants=network-online.target local-fs.target time-sync.target

    PartOf=ceph-osd.target

    [Service]

    LimitNOFILE=1048576

    LimitNPROC=1048576

    EnvironmentFile=-/etc/sysconfig/ceph

    Environment=CLUSTER=ceph

    ExecStart=/usr/bin/numactl -C 8-9 -m 0 /usr/bin/ceph-osd -f --cluster ${CLUSTER} --id 1 --setuser ceph --setgroup ceph

    ExecStartPre=/usr/lib/ceph/ceph-osd-prestart.sh --cluster ${CLUSTER} --id 1

    ExecReload=/bin/kill -HUP $MAINPID

    ProtectHome=true

    ProtectSystem=full

    PrivateTmp=true

    TasksMax=infinity

    Restart=on-failure

    StartLimitInterval=30min

    StartLimitBurst=30

    RestartSec=20s

    [Install]

    WantedBy=ceph-osd.target

    主要就是在ExecStart这个参数里进行修改,指定cpu和内存的分配node,然后start服务。

    实测发现,被isolcpu参数隔离的cpu,是不能通过上述方式启动的,原因是隔离出去的cpu没有在系统程序调度器中,解决办法就是加入 -a 参数,即选择cpu的时候检测所有的cpu,而不仅仅是检测系统可用的cpu

    但是,新的问题出现了,即使使用了 -a 参数,服务也正常起来了,但服务的运行有些奇怪,所有绑定了多个cpu的程序,都只使用了第一个指定的cpu,其他的cpu则全部处于空闲状态,例如:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25[tanweijie@ceph-c204 ~]$ sudo systemctl cat ceph-radosgw@rgw.ceph-c204.service

    # /etc/systemd/system/ceph-radosgw@rgw.ceph-c204.service

    [Unit]

    Description=Ceph rados gateway

    After=network-online.target local-fs.target time-sync.target

    Wants=network-online.target local-fs.target time-sync.target

    PartOf=ceph-radosgw.target

    [Service]

    LimitNOFILE=1048576

    LimitNPROC=1048576

    EnvironmentFile=-/etc/sysconfig/ceph

    Environment=CLUSTER=ceph

    ExecStart=/usr/bin/numactl -a -C 42-55 -m 1 /usr/bin/radosgw -f --cluster ${CLUSTER} --name client.%i --setuser ceph --setgroup ceph

    PrivateDevices=yes

    ProtectHome=true

    ProtectSystem=full

    PrivateTmp=true

    TasksMax=infinity

    Restart=on-failure

    StartLimitInterval=30s

    StartLimitBurst=5

    [Install]

    WantedBy=ceph-radosgw.target

    绑定了42-55号cpu,理应这些cpu都会被使用上,但是结果是

    single_cpu.png

    因而,在使用ioslcpu之后的cpu选择上,numactl似乎处理地有些问题,我将该问题反馈给了intel的linux相关开发人员,希望他们可以抽空修复;

    总结numactl的方法,如果绑定的是单个core,还是很不错的,它可以指定内存的分配,在numa架构的处理器上,这点是十分重要的

    systemd cpuaffinity

    systemd是最新的centos 7使用的服务管理程序,它替代了原来的SysV服务,成为了系统的第一个进程,进程pid为1,此后,所有进程都是从systemd fork出来,使用它能够非常方便地管理服务。

    systemctl就是管理服务的命令,它有许多子命令,这里就不详细赘述,只讲跟cpu亲和性有关的内容了;systemctl编辑管理服务最常用的是下面几个:

    1、systemctl cat 服务名 - 这个命令可以查看到对应服务的启动的详细配置文件

    2、systemctl start 服务名 - 启动服务

    3、systemctl stop 服务名 - 停止服务

    4、systemctl restart 服务名 - 重启服务

    5、systemctl edit 服务名 –full - 编辑服务启动配置文件,注意要加–full,否则打开的就是空配置文件

    使用systemctl edit命令打开配置文件进行编辑时,可以看到有几个配置域,例如rgw服务的配置文件:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25[tanweijie@ceph-c204 ~]$ sudo systemctl cat ceph-radosgw@rgw.ceph-c204.service

    # /etc/systemd/system/ceph-radosgw@rgw.ceph-c204.service

    [Unit]

    Description=Ceph rados gateway

    After=network-online.target local-fs.target time-sync.target

    Wants=network-online.target local-fs.target time-sync.target

    PartOf=ceph-radosgw.target

    [Service]

    LimitNOFILE=1048576

    LimitNPROC=1048576

    EnvironmentFile=-/etc/sysconfig/ceph

    Environment=CLUSTER=ceph

    ExecStart=/usr/bin/radosgw -f --cluster ${CLUSTER} --name client.%i --setuser ceph --setgroup ceph

    PrivateDevices=yes

    ProtectHome=true

    ProtectSystem=full

    PrivateTmp=true

    TasksMax=infinity

    Restart=on-failure

    StartLimitInterval=30s

    StartLimitBurst=5

    [Install]

    WantedBy=ceph-radosgw.target

    这里只关注[Service]域的配置,可以看到有很多个参数,最重要的就是ExecStart,它指定了进程的启动方式,详细的参数的说明,可以参考systemd.directives,讲的很详细了。我们这里最关注的是两个参数:

    1

    2

    3

    4

    5

    6

    7

    8

    9CPUAffinity=

    Controls the CPU affinity of the executed processes. Takes a list

    of CPU indices or ranges separated by either whitespace or

    commas. CPU ranges are specified by the lower and upper CPU

    indices separated by a dash. This option may be specified more

    than once, in which case the specified CPU affinity masks are

    merged. If the empty string is assigned, the mask is reset, all

    assignments prior to this will have no effect. See

    sched_setaffinity(2) for details.

    这里CPUAffinity就可以指定服务在启动的时候,使用哪种cpu亲和性,一旦配置,就可以使服务绑定运行在指定的cpu上,也就达到了我们的目的。另外我们可能还需要关注另外一个参数:

    1

    2

    3

    4Nice=

    Sets the default nice level (scheduling priority) for executed

    processes. Takes an integer between -20 (highest priority) and 19

    (lowest priority). See setpriority(2) for details.

    Nice参数指定了服务启动时的优先级情况,我们的想法就是让进程持久地运行在指定的cpu上,设置其优先级最高级别,也能防止进程的切换;进行了参数设置之后的配置例如:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27[tanweijie@ceph-c204 ~]$ sudo systemctl cat ceph-radosgw@rgw.ceph-c204.service

    # /etc/systemd/system/ceph-radosgw@rgw.ceph-c204.service

    [Unit]

    Description=Ceph rados gateway

    After=network-online.target local-fs.target time-sync.target

    Wants=network-online.target local-fs.target time-sync.target

    PartOf=ceph-radosgw.target

    [Service]

    LimitNOFILE=1048576

    LimitNPROC=1048576

    EnvironmentFile=-/etc/sysconfig/ceph

    Environment=CLUSTER=ceph

    ExecStart=/usr/bin/radosgw -f --cluster ${CLUSTER} --name client.%i --setuser ceph --setgroup ceph

    PrivateDevices=yes

    ProtectHome=true

    ProtectSystem=full

    PrivateTmp=true

    TasksMax=infinity

    Restart=on-failure

    StartLimitInterval=30s

    StartLimitBurst=5

    Nice=-20

    CPUAffinity=14 15 16 17 18 19 20 21 22 23 24 25 26 27

    [Install]

    WantedBy=ceph-radosgw.target

    这样进行配置后,htop可以看到效果:

    1524801837944.jpg

    这里设置的0-2号cpu绑定到了其他进程上,系统所有的进程绑定到了42-55号cpu上,其余cpu没有被绑定,因此不会被使用

    避免进程调度到已被绑定的cpu

    要阻止系统将进程调度到已被绑定的cpu上,有两种思路:

    1、不让系统程序调度器看到那些cpu,方法就是使用内核参数isolcpu,这样无论如何,系统都无法在这些cpu进行程序的调度(中断除外)

    2、即使程序调度器可以看到所有cpu,但可以设置cpu亲和性来强迫系统进程运行在特定的cpu上,这样就可以避免调度到未指定的cpu上

    未被使用的cpu并不是使用了isolcpu进行隔离的,而是在/etc/systemd/system.conf中对systemd进行了全局的cpu亲和性绑定,这样可以做到,就算所有的cpu都被系统程序调度器看到,除非在服务中指定了cpuaffinity,否则默认是不会调度到未绑定的cpu上,与isolcpu的功能基本一致;这里多说一句,isolcpu开始逐步被redhat抛弃,并且redhat在systemd中可以配置cpuaffinity,也有逐步摆脱numactl的意向

    最后要关注的点

    关于cpu的优化,了解numa架构并合理利用,理解cpu亲和性并实现绑定,关于处理器的优化基本上就完成了,在某些场合,如果发现业务运行时有较大的波动,排除是链路引起的问题之后,可以考虑在中断这块入手,将中断手动实现绑定,说不定能得到更稳定的性能

    本文作者:奋斗的松鼠 - tanweijie_2012@163.com

    本文链接:

    http://www.strugglesquirrel.com/2018/04/26/再谈系统调优关于CPU亲和性的处理/

    版权声明:

    本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 CN 许可协议。转载请注明出处!

    特别说明:

    本博客的第一手更新发布在微信公众号"奋斗的cepher",那里有更多干货等着你,如果喜欢我的文章,就请关注我的公众号吧

    本文浏览次数:

    展开全文
  • cpu绑定和cpu亲和性

    2021-03-13 11:36:05
    将进程/线程与cpu绑定,最直观的好处就是提高了cpu cache的命中率,从而减少内存访问损耗,提高程序的速度。我觉得在NUMA架构下,这个操作对系统运行速度的提升有较大的意义,而在SMP架构下,这个提升可能就比较小。...

    将进程/线程与cpu绑定,最直观的好处就是提高了cpu cache的命中率,从而减少内存访问损耗,提高程序的速度。我觉得在NUMA架构下,这个操作对系统运行速度的提升有较大的意义,而在SMP架构下,这个提升可能就比较小。这主要是因为两者对于cache、总线这些资源的分配使用方式不同造成的,NUMA每个cpu有自己的一套资源体系, SMP中每个核心还是需要共享这些资源的,从这个角度来看,NUMA使用cpu绑定时,每个核心可以更专注地处理一件事情,资源体系被充分使用,减少了同步的损耗。SMP由于一部分资源的共享,在进行了绑定操作后,受到的影响还是很大的。

    通过linux提供的几个api, 可以轻松地完成这个优化:

    #define _GNU_SOURCE

    #include 

    int sched_setaffinity(pid_t pid, size_t cpusetsize,cpu_set_t *mask);    //设定pid 绑定的cpu,

    int sched_getaffinity(pid_t pid, size_t cpusetsize,cpu_set_t *mask);    //查看pid 绑定的cpu。

    cpu_set_t  //是一个掩码数组,一共有1024位,每一位都可以对应一个cpu核心

    //以下宏,都是对这个掩码进行操作的。如果需要,一个进程是可以绑定多个cpu的。

    void CPU_ZERO(cpu_set_t *set);

    void CPU_SET(int cpu, cpu_set_t *set);

    void CPU_CLR(int cpu, cpu_set_t *set);

    int CPU_ISSET(int cpu, cpu_set_t *set);

    下面是一个实例。

    /*

    * @FileName: simple_affinity.c

    * @Author: wzj

    * @Brief:

    * 1. cpu affinity.  case

    * 2.在子线程中,会继承绑定的cpu..., 不过在子线程中,可以重新分配。

    *

    * @History:

    *

    *

    *

    * @Date: 2012年04月21日星期六12:56:14

    *

    */

    #include 

    #include 

    #include 

    #define __USE_GNU       //启用CPU_ZERO等相关的宏

    //#define _GNU_SOURCE

    #include 

    #include             //这个东西原来放在__USE_GNU宏之前,结果被编译器报错说CPU_ZERO未定义

    void* new_test_thread(void* arg)

    {

    cpu_set_t mask;

    int i = 0;

    int num = sysconf(_SC_NPROCESSORS_CONF);    //获取当前的cpu总数

    pthread_detach(pthread_self());

    CPU_ZERO(&mask);

    CPU_SET(1, &mask);      //绑定cpu 1

    if(sched_setaffinity(0, sizeof(mask), &mask) == -1)      //0 代表对当前线程/进程进行设置。

    {

    printf("set affinity failed..");

    }

    while(1)

    {

    CPU_ZERO(&mask);

    if(sched_getaffinity(0, sizeof(mask), &mask) == -1)

    {

    printf("get failed..\n");

    }

    for(i = 0; i 

    {

    if(CPU_ISSET(i, &mask))

    printf("new thread %d run on processor %d\n", getpid(), i);

    }

    while(1);

    sleep (1);

    }

    }      //while(1);      //如果觉得不明显,改成这个,

    void* child_test_thread(void* arg)

    {

    cpu_set_t mask;

    int i = 0;

    int num = sysconf(_SC_NPROCESSORS_CONF);

    pthread_detach(pthread_self());

    while(1)

    {

    CPU_ZERO(&mask);

    if(sched_getaffinity(0, sizeof(mask), &mask) == -1)

    {

    printf("get failed..\n");

    }

    for(i = 0; i 

    {

    if(CPU_ISSET(i, &mask))

    printf("child thread %d run on processor %d\n", getpid(), i);

    }

    sleep (1);

    }

    }

    int

    main(int argc, char* argv[])

    {

    int num = sysconf(_SC_NPROCESSORS_CONF);

    int created_thread = 0;

    int myid;

    int i;

    int j = 0;

    pthread_t ptid = 0;

    cpu_set_t mask;

    cpu_set_t get;

    if(argc != 2)

    {

    printf("usage: ./cpu num\n");

    return -1;

    }

    myid = atoi(argv[1]);

    printf("system has %i processor(s).\n", num);

    CPU_ZERO(&mask);

    CPU_SET(myid, &mask);

    if(sched_setaffinity(0, sizeof(mask), &mask) == -1)

    {

    printf("warning: set CPU affinity failed...");

    }

    int ret = pthread_create(&ptid, NULL, new_test_thread, NULL);

    if(ret)

    {

    return -1;

    }

    ret = pthread_create(&ptid, NULL, child_test_thread, NULL);

    if(ret)

    {

    return -1;

    }

    while(1)

    {

    CPU_ZERO(&get);

    if(sched_getaffinity(0, sizeof(get), &get) == -1)

    {

    printf("can't get cpu affinity...");

    }

    for(i = 0; i 

    {

    if(CPU_ISSET(i, &get))

    {

    printf("this process %d is runing on procesor:%d\n", getpid(), i);

    }

    }

    sleep(1);

    }

    //while(1); //使用这个更明显

    return 0;

    }

    编译:

    gcc -o cpu simple_affinity.c -lpthread

    执行./cpu [cpu num / masks] ,使用top观察cpu使用状况。 使用./cpu 0 时,可以发现,两颗核心使用率都比较高, 使用./cpu 1时,可以发现,1核的压力比较重。

    当然还可以对线程进行cpu绑定。

    #define _GNU_SOURCE

    #include 

    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);

    这个介绍了使用的时机,比较经典:http://www.ibm.com/developerworks/cn/linux/l-affinity.html

    展开全文
  • 线程设置CPU亲和性demo

    2021-10-20 10:52:00
    #define _GNU_SOURCE 1 #include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<pthread.h> #include<time.h> #include<sched.h>... c = sched_getcpu()..
  • CPU亲和性

    多人点赞 热门讨论 2021-09-08 17:19:11
    什么是cpu亲和性 linux操作系统的cpu亲和性特征 linux操作系统中修改CPU亲和性地手段 什么是cpu亲和性 cpu的亲和性,进程要在某个给定的cpu上尽量长时间的运行而不被迁移到其他处理器的倾向性,进程迁移的频率小...
  • 过去几十年,各大公司致力于提高CPU晶体管密度和提高CPU工作频率,使得CPU的性能提升基本符合摩尔定律。但随着工艺不断发展,晶体管密度提升已经接近物理极限,CPU工作频率也由于功耗和发热的制约而无法继续提升。在...
  • 线程/进程和核绑定(CPU亲和性

    千次阅读 2021-03-01 15:04:13
    文章目录前言一、CPU亲和性1 前言2 为何要手动绑定线程/进程到CPU核3 多进程和多线程在多核CPU上运行:4 应用场景举例二、Linux的CPU亲和性特征1 软亲和性2 硬亲和性3 硬亲和性使用场景三、查看CPU的核1 使用指令2 ...
  • Linux中CPU亲和性(affinity)

    千次阅读 2018-08-03 16:13:03
     让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高的CPU的运行效率。  我们常听到的双核四线程/四核八线程指的就是支持超线程技术的CPU. 物理CPU:机器上安装的...
  • 何为CPU亲和性 CPU亲和性,进程要在某个给定的 CPU 上尽量长时间地运行而不被迁移到其他处理器的倾向性,进程迁移的频率小就意味着产生的负载小。亲和性一词是从affinity翻译来的,实际可以称为CPU绑定。 在...
  • 1. 什么是cpu亲和性(affinity) CPU的亲和性,就是进程要在指定的 CPU 上尽量长时间地运行而不被迁移到其他处理器;简单点的描述就是将指定的进程或线程绑定到相应的cpu上。 在多核运行的机器上,每个CPU本身自己...
  • 设置cpu亲和性 How to set one task’s CPU affinity quickly? 如何快速设置一个任务的CPU亲和力? 1, Get this task’s ID 1,获取此任务的ID # taskset -pc PID2, Set this task’s CPU affinity 2,设置此任务...
  • Linux:设置进程(线程)的CPU亲和性 一、进程的CPU亲和性的获取(get)或者设置(set) int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask); int sched_getaffinity(pid_t pid, size_t ...
  • Linux中CPU亲和性(affinity)

    千次阅读 2020-02-25 02:21:12
    一. 准备知识: 并行:两件(多件)事情在...物理CPU:机器上实际安装的CPU个数,比如说你的主板上安装了一块8核CPU,那么物理CPU个数就是1个,所以物理CPU个数就是主板上安装的CPU个数。 逻辑CPU:一般情况,我们...
  • 进程,线程,内核设置cpu亲和性

    千次阅读 2018-09-18 16:50:19
    进程与cpu绑定 sched_setaffinity可以将某个进程绑定到一个特定的CPU。 SCHED_SETAFFINITY(2) Linux Programmer's Manual ...
  • 实例 做ssl加速卡(高并发)测试又遇到相同的问题,多队列网卡软中断过高,记录备忘 场景:nginx模拟业务服务器,worker不绑定;网卡队列亲和性不设置 结果:那叫一塌糊涂,3w TPS 0号CPU就满了, 其中si多...
  • cat /proc/interrupts : 查看中断都发生在哪些cpu上 cat /proc/irq/80/smp_affinity : 查看某个中断(80号)亲和性绑定在哪个cpu
  • 关于CPU亲和性的测试

    2021-03-13 11:36:06
    今天看到运维的同事在配置nginx的CPU亲和性时候,运维同事说他在所有的机器上都是按照8核的方式来配置worker进程的CPU亲和性的。但我觉得就是有点不太对劲,就查了一下nginx的处理worker_cpu_affinity的源代码,发现...
  • NGINX原理 之 CPU绑定 CPU亲和性
  • Java线程CPU亲和性工具

    2021-03-05 12:03:12
    Thread Affinity为什么需要线程的CPU亲和性应用通过多线程的方式执行,多数情况下线程能够被合理的调度。但在某些情况下某个重要的线程被暂停,而时间片被分配给Thread Affinity为什么需要线程的CPU亲和性应用通过多...
  • cpu优化-cpu亲和性

    2021-05-18 09:27:32
    cpu亲和性 taskset命令可以将进程绑核,格式为taskset -p -c cpu-list pid,其中cpu-list是数字化的cpu列表,从0开始。多个不连续的cpu可用逗号连接,连续的可用-连接,比如0,2,5-11等。 举例: #我现在系统中存在...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,482
精华内容 3,392
关键字:

cpu亲和性

友情链接: bpandcmac.rar