日期:2014-05-16  浏览次数:20618 次

linux下让进程运行在指定的cpu上
收藏
最近负责的svr压力比较大,业务逻辑有点复杂,能优化的地方已经全部优化了,

目前每秒3k次,cpu负载还是比较高

top看一下,4核的cpu负载不是太均衡,打算考虑一下将业务进程指定到3个cpu上运行,另外一个cpu专门负责处理网络收发包;打算尝试一下,如果还是不行,再过段时间,访问量再增加的话,就要加机器了,呜呜

补充:今天测试了一下,效果挺好,同样进程数的情况下,进行cpu绑定

每个cpu都利用起来了,负载也比不绑定的情况下好了很多

分析一下有效果的原因:

看了《linux内核设计与实现》的42节,觉得人为控制一下cpu的绑定还是有用处的
1、linux的SMP负载均衡是基于进程数的,每个cpu都有一个可执行进程队列,只有当其中一个cpu的可执行队列里进程数比其他cpu队列进程数多25%时,才会将进程移动到另外空闲cpu上,也就是说cpu0上的进程数应该是比其他cpu上多,但是会在25%以内


2、我们的业务中耗费cpu的分四种类型,(1)网卡中断(2)1个处理网络收发包进程(3)耗费cpu的n个worker进程(4)其他不太耗费cpu的进程

    基于1中的 负载均衡是针对进程数,那么(1)(2)大部分时间会出现在cpu0上,(3)的n个进程会随着调度,平均到其他多个cpu上,(4)里的进程也是随着调度分配到各个cpu上;

当发生网卡中断的时候,cpu被打断了,处理网卡中断,那么分配到cpu0上的worker进程肯定是运行不了的

其他cpu上不是太耗费cpu的进程获得cpu时,就算它的时间片很短,它也是要执行的,那么这个时候,你的worker进程还是被影响到了;按照调度逻辑,一种非常恶劣的情况是:(1)(2)(3)的进程全部分配到cpu0上,其他不太耗费cpu的进程数很多,全部分配到cpu1,cpu2,cpu3上。。那么网卡中断发生的时候,你的业务进程就得不到cpu了

如果从业务的角度来说,worker进程运行越多,肯定业务处理越快,人为的将它捆绑到其他负载低的cpu上,肯定能提高worker进程使用cpu的时间

找了个例子:

现在多CPU的趋势越来越大了. 有时候为了更好地操作机器, 需要将某个进程绑定到具体的CPU上去. 下面给出了一个进程绑定到具体的CPU上去的一个例子.

view plaincopy to clipboardprint?
·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······15001.#include<stdlib.h>  
02.#include<stdio.h>  
03.#include<sys/types.h>  
04.#include<sys/sysinfo.h>  
05.#include<unistd.h>  
06. 
07.#define __USE_GNU  
08.#include<sched.h>  
09.#include<ctype.h>  
10.#include<string.h>  
11. 
12.int main(int argc, char* argv[])  
13.{  
14.        int num = sysconf(_SC_NPROCESSORS_CONF);  
15.        int created_thread = 0;  
16.        int myid;  
17.        int i;  
18.        int j = 0;  
19. 
20.        cpu_set_t mask;  
21.        cpu_set_t get;  
22. 
23.        if (argc != 2)  
24.        {  
25.                printf("usage : ./cpu num\n");  
26.                exit(1);  
27.        }  
28. 
29.        myid = atoi(argv[1]);  
30. 
31.        printf("system has %i processor(s). \n", num);  
32. 
33.        CPU_ZERO(&mask);  
34.        CPU_SET(myid, &mask);  
35. 
36.        if (sched_setaffinity(0, sizeof(mask), &mask) == -1)  
37.        {  
38.                printf("warning: could not set CPU affinity, continuing...\n");  
39.        }  
40.        while (1)  
41.        {  
42. 
43.&nbs