cpu_set_t的定义
# define __CPU_SETSIZE 1024
# define __NCPUBITS (8 * sizeof (__cpu_mask))
typedef unsigned long int __cpu_mask;
# define __CPUELT(cpu) ((cpu) / __NCPUBITS)
# define __CPUMASK(cpu) ((__cpu_mask) 1 << ((cpu) % __NCPUBITS))
typedef struct
{
__cpu_mask __bits[__CPU_SETSIZE / __NCPUBITS];
} cpu_set_t;
# define __CPU_ZERO(cpusetp) \
do { \
unsigned int __i; \
cpu_set_t *__arr = (cpusetp); \
for (__i = 0; __i < sizeof (cpu_set_t) / sizeof (__cpu_mask); ++__i) \
__arr->__bits[__i] = 0; \
} while (0)
# define __CPU_SET(cpu, cpusetp) \
((cpusetp)->__bits[__CPUELT (cpu)] |= __CPUMASK (cpu))
# define __CPU_CLR(cpu, cpusetp) \
((cpusetp)->__bits[__CPUELT (cpu)] &= ~__CPUMASK (cpu))
# define __CPU_ISSET(cpu, cpusetp) \
(((cpusetp)->__bits[__CPUELT (cpu)] & __CPUMASK (cpu)) != 0)
上面几个宏与函数的具体用法:
cpu.c
#include
#include
#include
#include
#include
#define __USE_GNU
#include
#include
#include
int main(int argc, char* argv[])
{
int num = sysconf(_SC_NPROCESSORS_CONF);
int created_thread = 0;
int myid;
int i;
int j = 0;
cpu_set_t mask;
cpu_set_t get;
if (argc != 2)
{
printf("usage : ./cpu num\n");
exit(1);
}
myid = atoi(argv[1]);
printf("system has %i processor(s). \n", num);
CPU_ZERO(&mask);
CPU_SET(myid, &mask);
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
{
printf("warning: could not set CPU affinity, continuing...\n");
}
while (1)
{
CPU_ZERO(&get);
if (sched_getaffinity(0, sizeof(get), &get) == -1)
{
printf("warning: cound not get cpu affinity, continuing...\n");
}
for (i = 0; i < num; i++)
{
if (CPU_ISSET(i, &get))
{
printf("this process %d is running processor : %d\n",getpid(), i);
}
}
}
return 0;
}
在我的机器上sizeof(cpu_set_t)的大小为128,即一共有1024位.第一位代表一个CPU号.某一位为1则表示某进程可以运行在该位所代表的cpu上.
例如CPU_SET(1, &mask);
则mask所对应的第2位被设置为1.
此时如果printf("%d\n", mask.__bits[0]);就打印出2.表示第2位被置为1了.
具体我是参考man sched_setaffinity文档中的函数的.
然后再参考了一下IBM的 developerWorks上的一个讲解.
1,可以使用mpstat指令,UNIX系统下,mpstat有相当完备的选项可供使用,而在笔者的REDHAT AS5中,mpstat只有区区-P选项。以下是笔者运行mpstat –P ALL的截图,可以看到各个CPU的运行情况。
[kxu@nothung MovieInfo]$ mpstat -P ALL
Linux 2.6.18-8.el5 (nothung.localdomain) 02/03/2008
10:50:43 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
10:50:43 PM all 32.82 0.00 4.73 0.10 0.00 0.13 0.00 62.22 1035.82
10:50:43 PM 0 26.73 0.00 3.96 0.08 0.00 0.13 0.00 69.08 141.13
2,top,然后输入“1”,查看cpu状态输入大写“H”,查看程序的线程信息
系统调用是许多开发人员经常忽视的障碍。影响可扩展性的 2 种最常见的意外调用是 malloc 和 gettimeofday。malloc 调用会遇到它里面的锁,它可序列化调用者和执行。如果线程分配 1 个大型内存块,然后运行较长时间,那么该费用就没那么急需。使用更高效的内存分配器,顺畅运行多次调用 malloc 的应用。英特尔线程构建模块包括可为该目的而极致扩展的内存分配调用。其它可用的第三方内存分配库也可比 malloc 表现出色。在第二个示例中,当 200 多条线程同时调用 gettimeofday,它也可能像顺序区域一样运行。只有一条线程调用 gettimeofday。使用本地计时器在线程内计时。可通过配置使 gettimeofday 调用恢复本地内核计数器或全局处理器计数器,该技巧假设它正利用全局处理器而非本地内核 tsc 计数器。考虑其它可能成为障碍的系统调用和库,使用替代选项或尽可能不使用它们。
cpu缓存相关网站介绍
http://software.intel.com/zh-cn/articles/optimization-and-performance-tuning-for-intel-xeon-phi-coprocessors-part-1-optimization
http://www.cnblogs.com/yanlingyin/archive/2012/02/15/thinkingincache.html