把一个或多个进/线程绑定到不相关的cpu核中,可以有效的减少线程在多个cpu里头切换,仅能运行在绑定的cpu核中。
那么cpu核被绑定后,是否意味着该核就只能被某个进程独占呢,显然是否定的。想想,如果4核的cpu,分4个不同的进程绑定了,那岂不是其他进程就无法运行了? 所有绑核仅仅是为了使进程在某个核中运行,而不是禁止其他进程使用该核。我们可以把多个进程绑定在同一个核中。
当然,我们应该把消耗高的进程绑定到不同的核中,这样可以提供性能,因为减少上下文的切换呀。
以下是一个绑核的例子,我们可以运行多次该例子,让多个进程绑定在同一个核。
#include <iostream>
#include <thread>
#include<sys/types.h>
#include<sys/sysinfo.h>
using namespace std;
void func(int input_num) {
cpu_set_t mask;
cpu_set_t get;
printf("the thread is:%d\n", input_num);
CPU_ZERO(&mask);
CPU_SET(input_num, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
{
printf("warning: could not set CPU affinity, continuing...\n");
}
CPU_ZERO(&get);
if (sched_getaffinity(0, sizeof(get), &get) == -1)
{
printf("warning: cound not get thread affinity, continuing...\n");
}
for (unsigned i = 0; i < 4; i++)
{
if (CPU_ISSET(i, &get))
{
printf("this thread %d is running processor : %d\n", input_num, i);
}
}
double aa = 10.123;
double result[1028];
for (unsigned int i = 1; ;++i)
{
result[i % 1024] = aa / i;
if (i % 1000000000 == 0) {
CPU_ZERO(&get);
if (sched_getaffinity(0, sizeof(get), &get) == -1)
{
printf("warning: cound not get thread affinity, continuing...\n");
}
for (int tmp = 0; tmp < 4; tmp++)
{
if (CPU_ISSET(tmp, &get))
{
printf("this thread %d(%p) is running processor : %d\n", input_num, &input_num, tmp);
}
}
}
}
}
int main() {
thread aa = std::thread(func,3);
thread bb = std::thread(func,2);
//thread cc = std::thread(func,1);
//thread dd = std::thread(func,0);
cout << "hello world" << endl;
aa.join();
bb.join();
//cc.join();
//dd.join();
return 0;
}
查看测试输出:
top - 13:55:06 up 5:09, 6 users, load average: 2.00, 2.01, 1.99
Threads: 3 total, 2 running, 1 sleeping, 0 stopped, 0 zombie
%Cpu(s): 50.1 us, 0.1 sy, 0.0 ni, 49.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 2048272 total, 47324 free, 902628 used, 1098320 buff/cache
KiB Swap: 2097148 total, 1927248 free, 169900 used. 1011772 avail Mem
PID PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND P TIME SWAP
3449 20 0 31192 1096 916 R 99.9 0.1 247:33.88 main 3 247:33 0
3450 20 0 31192 1096 916 R 99.9 0.1 247:33.83 main 2 247:33 0
3448 20 0 31192 1096 916 S 0.0 0.1 0:00.00 main 0 0:00 0
[df@localhost ~]$ taskset -c -p 3448
pid 3448's current affinity list: 0
[df@localhost ~]$ taskset -c -p 3449
pid 3449's current affinity list: 3
[df@localhost ~]$ taskset -c -p 3450
pid 3450's current affinity list: 2
[df@localhost ~]$
[df@localhost ~]$ top -H
top - 13:26:57 up 4:40, 6 users, load average: 2.00, 2.01, 1.99
Threads: 431 total, 3 running, 428 sleeping, 0 stopped, 0 zombie
%Cpu(s): 50.8 us, 1.5 sy, 0.0 ni, 47.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 2048272 total, 286624 free, 832840 used, 928808 buff/cache
KiB Swap: 2097148 total, 1926024 free, 171124 used. 1121500 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
3449 df+ 20 0 31192 1096 916 R 99.9 0.1 219:25.35 main
3450 df+ 20 0 31192 1096 916 R 93.8 0.1 219:25.30 main
4648 root 20 0 0 0 0 S 6.2 0.0 0:00.10 kworker/1:1
6317 df+ 20 0 158000 2440 1500 R 6.2 0.1 0:00.01 top
1 root 20 0 190932 2848 1520 S 0.0 0.1 0:01.54 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 20 0 0 0 0 S 0.0 0.0 0:00.42 ksoftirqd/0
5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:+
7 root rt 0 0 0 0 S 0.0 0.0 0:00.01 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:01.19 rcu_sched
10 root rt 0 0 0 0 S 0.0 0.0 0:00.05 watchdog/0
12 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs
13 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns
14 root 20 0 0 0 0 S 0.0 0.0 0:00.00 khungtaskd
15 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 writeback
16 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kintegrityd
关于接口的更多说明,请看文章: Linux中CPU亲和性(affinity)