|
沙发

楼主 |
发表于 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 运行与输出: |
|