本节我们主要介绍一下nginx中,进程cpu亲和性设置相关的实现。
1. os/unix/ngx_setaffinity.h头文件
当前我们在ngx_auto_config.h头文件中有如下定义:
#ifndef NGX_HAVE_SCHED_SETAFFINITY
#define NGX_HAVE_SCHED_SETAFFINITY 1
#endif
因此这里我们实际执行的是:
2. os/unix/ngx_setaffinity.c源文件
当前我们有定义NGX_HAVE_SCHED_SETAFFINITY
宏,因此这里我们使用的是ngx_setaffinity()的后一个实现。程序较为简单,首先会打印一下当前进程绑定的CPU集合:
然后再调用sched_setaffinity()函数设置进程的亲和性。下面我们介绍一下亲和性方面的一些内容:
2.1 设置和获取一个线程的亲和性
一个线程的CPU亲和性掩码决定了该线程跑在哪个(些)CPU上比较合适。在一个多核系统上,设置CPU亲和性掩码可以获得较好的性能。例如,将一个CPU单独贡献给一个线程(其他线程绑定到其他CPU上),这样就能够保证该线程获得最大的执行速度。限制线程运行在一个单独的CPU上可以避免线程因切换CPU导致的cache失效而产生的性能损失。
一个CPU的亲和性掩码由一个cpu_set_t结构来表示。
2.2 相关辅助宏定义
另外有一个常量CPU_SETSIZE
,当前一般被定义为1024。大部分情况下,其已经远远超过了我们当前电脑CPU的个数了。
2.3 示例
1) 示例1
程序test.c:
编译运行:
[root@localhost test-src]# gcc -o test test.c
[root@localhost test-src]# ./test
cpu count: 0 , alloc size: 0
cpu count: 1 , alloc size: 8
cpu count: 10 , alloc size: 8
cpu count: 100 , alloc size: 16
cpu count: 1000 , alloc size: 128
cpu count: 1023 , alloc size: 128
cpu count: 1024 , alloc size: 128
cpu count: 1025 , alloc size: 136
sizeof(cpu_set_t): 128
83 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
2) 示例2
程序test2.c:
编译运行:
[root@localhost test-src]# gcc -o test2 test2.c
[root@localhost test-src]# ./test2
cpu affinity set
在另外一个窗口执行top命令:
[root@localhost test-src]# top //按下数字键1,查看每个逻辑CPU使用率
top - 05:13:28 up 3:32, 3 users, load average: 0.95, 0.59, 0.29
Tasks: 163 total, 2 running, 161 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 10058704 total, 9185284 free, 397576 used, 475844 buff/cache
KiB Swap: 5112828 total, 5112828 free, 0 used. 9328352 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
10497 root 20 0 4160 340 272 R 100.0 0.0 1:11.27 test2
312 root 20 0 0 0 0 S 0.3 0.0 0:03.65 xfsaild/sda3
8864 root 20 0 0 0 0 S 0.3 0.0 0:01.35 kworker/0:0
10498 root 20 0 157724 2292 1556 R 0.3 0.0 0:00.06 top
1 root 20 0 128096 6704 3952 S 0.0 0.1 0:03.95 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.02 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H
6 root 20 0 0 0 0 S 0.0 0.0 0:00.36 kworker/u256:0
7 root rt 0 0 0 0 S 0.0 0.0 0:00.08 migration/0
8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh
9 root 20 0 0 0 0 S 0.0 0.0 0:02.35 rcu_sched
10 root rt 0 0 0 0 S 0.0 0.0 0:00.04 watchdog/0
11 root rt 0 0 0 0 S 0.0 0.0 0:00.03 watchdog/1
12 root rt 0 0 0 0 S 0.0 0.0 0:00.12 migration/1
13 root 20 0 0 0 0 S 0.0 0.0 0:00.06 ksoftirqd/1
我们可以看到test2进程被绑定到cpu3上,cpu3的使用率为100%。
[参看]:
-
线程绑定CPU核-sched_setaffinity
-
c语言设置cpu affinity