java设置cpu亲和性_cpu绑定和cpu亲和性

将进程/线程与cpu绑定,最直观的好处就是提高了cpu cache的命中率,从而减少内存访问损耗,提高程序的速度。我觉得在NUMA架构下,这个操作对系统运行速度的提升有较大的意义,而在SMP架构下,这个提升可能就比较小。这主要是因为两者对于cache、总线这些资源的分配使用方式不同造成的,NUMA每个cpu有自己的一套资源体系, SMP中每个核心还是需要共享这些资源的,从这个角度来看,NUMA使用cpu绑定时,每个核心可以更专注地处理一件事情,资源体系被充分使用,减少了同步的损耗。SMP由于一部分资源的共享,在进行了绑定操作后,受到的影响还是很大的。

通过linux提供的几个api, 可以轻松地完成这个优化:

#define _GNU_SOURCE

#include 

int sched_setaffinity(pid_t pid, size_t cpusetsize,cpu_set_t *mask);    //设定pid 绑定的cpu,

int sched_getaffinity(pid_t pid, size_t cpusetsize,cpu_set_t *mask);    //查看pid 绑定的cpu。

cpu_set_t  //是一个掩码数组,一共有1024位,每一位都可以对应一个cpu核心

//以下宏,都是对这个掩码进行操作的。如果需要,一个进程是可以绑定多个cpu的。

void CPU_ZERO(cpu_set_t *set);

void CPU_SET(int cpu, cpu_set_t *set);

void CPU_CLR(int cpu, cpu_set_t *set);

int CPU_ISSET(int cpu, cpu_set_t *set);

下面是一个实例。

/*

* @FileName: simple_affinity.c

* @Author: wzj

* @Brief:

* 1. cpu affinity.  case

* 2.在子线程中,会继承绑定的cpu..., 不过在子线程中,可以重新分配。

*

* @History:

*

*

*

* @Date: 2012年04月21日星期六12:56:14

*

*/

#include 

#include 

#include 

#define __USE_GNU       //启用CPU_ZERO等相关的宏

//#define _GNU_SOURCE

#include 

#include             //这个东西原来放在__USE_GNU宏之前,结果被编译器报错说CPU_ZERO未定义

void* new_test_thread(void* arg)

{

cpu_set_t mask;

int i = 0;

int num = sysconf(_SC_NPROCESSORS_CONF);    //获取当前的cpu总数

pthread_detach(pthread_self());

CPU_ZERO(&mask);

CPU_SET(1, &mask);      //绑定cpu 1

if(sched_setaffinity(0, sizeof(mask), &mask) == -1)      //0 代表对当前线程/进程进行设置。

{

printf("set affinity failed..");

}

while(1)

{

CPU_ZERO(&mask);

if(sched_getaffinity(0, sizeof(mask), &mask) == -1)

{

printf("get failed..\n");

}

for(i = 0; i 

{

if(CPU_ISSET(i, &mask))

printf("new thread %d run on processor %d\n", getpid(), i);

}

while(1);

sleep (1);

}

}      //while(1);      //如果觉得不明显,改成这个,

void* child_test_thread(void* arg)

{

cpu_set_t mask;

int i = 0;

int num = sysconf(_SC_NPROCESSORS_CONF);

pthread_detach(pthread_self());

while(1)

{

CPU_ZERO(&mask);

if(sched_getaffinity(0, sizeof(mask), &mask) == -1)

{

printf("get failed..\n");

}

for(i = 0; i 

{

if(CPU_ISSET(i, &mask))

printf("child thread %d run on processor %d\n", getpid(), i);

}

sleep (1);

}

}

int

main(int argc, char* argv[])

{

int num = sysconf(_SC_NPROCESSORS_CONF);

int created_thread = 0;

int myid;

int i;

int j = 0;

pthread_t ptid = 0;

cpu_set_t mask;

cpu_set_t get;

if(argc != 2)

{

printf("usage: ./cpu num\n");

return -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: set CPU affinity failed...");

}

int ret = pthread_create(&ptid, NULL, new_test_thread, NULL);

if(ret)

{

return -1;

}

ret = pthread_create(&ptid, NULL, child_test_thread, NULL);

if(ret)

{

return -1;

}

while(1)

{

CPU_ZERO(&get);

if(sched_getaffinity(0, sizeof(get), &get) == -1)

{

printf("can't get cpu affinity...");

}

for(i = 0; i 

{

if(CPU_ISSET(i, &get))

{

printf("this process %d is runing on procesor:%d\n", getpid(), i);

}

}

sleep(1);

}

//while(1); //使用这个更明显

return 0;

}

编译:

gcc -o cpu simple_affinity.c -lpthread

执行./cpu [cpu num / masks] ,使用top观察cpu使用状况。 使用./cpu 0 时,可以发现,两颗核心使用率都比较高, 使用./cpu 1时,可以发现,1核的压力比较重。

当然还可以对线程进行cpu绑定。

#define _GNU_SOURCE

#include 

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize,

const cpu_set_t *cpuset);

int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize,

cpu_set_t *cpuset);

这个介绍了使用的时机,比较经典:http://www.ibm.com/developerworks/cn/linux/l-affinity.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值