绑定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

 

 

你可能感兴趣的:(cpu)