绑定CPU

处理器的亲和性

软亲和性(affinity) 意味着进程并不会在处理器之间频繁迁移,而 硬亲和性(affinity) 则意味着进程需要在您指定的处理器上运行。

通常 Linux 内核都可以很好地对进程进行调度,在应该运行的地方运行进程(这就是说,在可用的处理器上运行并获得很好的整体性能)。内核包含了一些用来检测 CPU
之间任务负载迁移的算法,可以启用进程迁移来降低繁忙的处理器的压力。

一般情况下,在应用程序中只需使用缺省的调度器行为。然而,您可能会希望修改这些缺省行为以实现性能的优化。

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

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

Linux 内核 API 提供了一些方法,让用户可以修改位掩码或查看当前的位掩码:

  • sched_setaffinity() (用来修改位掩码)
  • sched_getaffinity() (用来查看当前的位掩码)

注意,cpu_affinity 会被传递给子线程,因此应该适当地调用 sched_setaffinity

相关函数包含在/usr/include/sched.h头文件中,并且需要定义#define __USE_GNU为了使用其中的一些宏。

 1 #include<stdlib.h> 
 2 #include<stdio.h> 
 3 #include<sys/types.h> 
 4 #include<sys/sysinfo.h> 
 5 #include<unistd.h> 
 6 #include<sched.h> 
 7 #include<ctype.h> 
 8 #include<string.h> 
 9 #define __USE_GNU 
10 
11 inline int set_cpu(int i) 
12 { 
13     int cpu_nums = sysconf(_SC_NPROCESSORS_CONF);//获取cpu个数
14    cpu_set_t mask; 
15   
16     CPU_ZERO(&mask); 
17     printf("system has %i processor(s). \n", cpu_nums); 
18 
19     if(i < cpu_nums) 
20     { 
21         CPU_SET(i,&mask); 
22          if(-1 == sched_setaffinity(gettid(),sizeof(&mask),&mask)) 
23         { 
24             printf("warning: could not set CPU affinity, continuing...\n");
25             return -1; 
26          } 
27      } 
28     return 0; 
29 } 
30 
31 
32 int main(int argc, char* argv[]) 
33 { 
34  
35     int created_thread = 0; 
36     int myid; 
37     int i; 
38     int j = 0; 
39     cpu_set_t get; 
40 
41     if (argc != 2) 
42     { 
43         printf("usage : ./cpu num\n"); 
44         exit(1); 
45     } 
46     myid = atoi(argv[1]); 
47 
48     set_cpu(myid) 
49     int num = sysconf(_SC_NPROCESSORS_CONF);   
50     while (1) 
51     { 
52         CPU_ZERO(&get); 
53         if (sched_getaffinity(0, sizeof(get), &get) == -1) 
54         { 
55             printf("warning: cound not get cpu affinity, continuing...\n"); 
56          } 
57         for (i = 0; i < num; i++) 
58         { 
59             if (CPU_ISSET(i, &get)) 
60             { 
61                 printf("this process %d is running processor : %d\n",getpid(), i); 
62             } 
63         } 
64     } 
65     return 0; 
66 }

 

 参考文献

http://www.ibm.com/developerworks/cn/linux/l-affinity.html

 

 

posted @ 2013-10-09 21:32  TheBug  阅读(959)  评论(0编辑  收藏  举报