| 
 | 
沙发
 
 
 楼主 |
发表于 2010-9-12 21:55:15
|
只看该作者
 
 
 
CPU 亲和性. CPU_SET
CPU_SET 的也是个函数宏定义,它的原型是:void CPU_SET(int cpu, cpu_set_t *set);  
查看 seched.h 里的具体定义:#define CPU_SET(cpu, cpusetp)   __CPU_SET_S (cpu, sizeof (cpu_set_t), cpusetp)  在 CPU_SET() 里,第 1 个参数表示第几个 cpu ,第 2 个参数是一个 cpu_set_t 类型指针。 
在 __CPU_SET_S 里,第 2 个参数在 32 位机里,它为 128 。 
 
下面进一步看 __CPU_SET_S 的定义:# define __CPU_SET_S(cpu, setsize, cpusetp) \\ 
 (__extension__                                                              \\ 
 ({ size_t __cpu = (cpu);                                                   \\ 
 __cpu < 8 * (setsize)                                                   \\ 
 ? (((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)]               \\ 
 |= __CPUMASK (__cpu))                                                \\ 
 : 0; }))  上面,setsize * 8 = 1024 ,也就是一个可以有 1024 个位来设置 1024 个 CPU 的掩码。宏中的第 2 条语句的定义的意思是,如果输入的 cpu 的值大于 1024,那么就设置第 1 个 CPU 的掩码(第 0 位)。 
 
上面说过,cpu_set_t 实际上是一个只包含整型数组的结构体。所以,在 cpusetp->__bits (__bit 是数组名)前面加上 (__cpu_mask *) 进行类型转换(__cpu_mask 也是无符号整型),说明这是一个无符号整型数组。 
 
再看数组元素的下标的定义:# define __CPUELT(cpu)  ((cpu) / __NCPUBITS)  从上面知道,__NCPUBITS 是 32 ,刚好是 4 个字节,为一个整型大小(实际上也就是无符号整型数组中的元素大小)。 
 
这里假设输入参数 cpu 是 1,,那么 cpu / __NCPUBITS 为 0. 从((__cpu_mask *) ((cpusetp)->__bits))[__CPUELT (__cpu)]  知道,我们要设定 CPU 是在数组中的第一个元素里。__CPUMASK 的定义为:# define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))  上面表示 1 向左移动 cpu % __NCPUBITS 位。然后,将这个位或起来(置位)。 
 
所以,CPU_SET 中的第 1 个 参数表示的是第 X 个 CPU,而不是一共多少个 CPU 。 
 
从下面的 C 代码也可以看到这一点:#define __USE_GNU 
 #include <sched.h> 
 #include <stdio.h> 
  
 int main() 
 { 
     cpu_set_t cpuset; 
     cpu_set_t *cpusetp = &cpuset; 
     int *p = (int *)cpusetp; 
      
     CPU_ZERO (&cpuset); 
  
     CPU_SET (0, &cpuset); 
     printf ("%d\\n", p[0]); 
  
      
     CPU_SET (1, &cpuset); 
     printf ("%d\\n", p[0]); 
      
  
     CPU_SET (2, &cpuset); 
     printf ("%d\\n", p[0]); 
  
  
     CPU_SET (3, &cpuset); 
     printf ("%d\\n", p[0]); 
  
     CPU_SET (256, &cpuset); 
     printf ("%d\\n", p[8]); 
      
  
     return (0); 
 }  编译方法:gcc -g -D_GNU_SOURCE cpu_set_t.c -o cpu_set_t  运行与输出: |   
 
 
 
 |