linux cpu绑定

一、说明

运行环境:虚拟机 gentoo4.4.6 3核心cpu

          gcc 4.9.3

参考资料:文中部分代码和内容参照以下网络资料,如有侵权,请及时联系。

         Linux CPU affinityhttp://blog.csdn.net/yfkiss/article/details/7464968

         top指令:http://developer.51cto.com/art/201509/492641.htm

                  http://www.cnblogs.com/yjf512/p/3383915.html

        Linux进程或线程绑定到CPU

                  http://www.linuxidc.com/Linux/2015-04/116867.htm

                  http://0987654321.blog.51cto.com/6934559/1409979

        unix环境高级编程》第11章:线程

二、中断绑定cpu

 以网卡中断为例:对于网卡中断来说,有时会因为大量的网络中断导致cpu繁忙,可以通过将网卡中断绑定到特定的cpu,这样即使网络再繁忙,也不会使cpu响应其它请求变得太慢。

 

图中说明网卡中断为19,其smp_affinity 0x07,注意,这个值是以16进制表示,换成二进制就是0111, 也就说明3cpu核心都可以相应网卡中断(虚拟机中设定了该系统使用3cpu),

   如果只让网卡中断绑定一个cpu,例如cpu0 ,  可以使用下面的方法:

     Echo ‘1’ > /proc/irq/19/smp_affinity

具体细节可以参看内核源码文档: 内核源码:Documentation/IRQ-affinity

 

三、进程(线程)运行中绑定cpu

3.1单线程进程消耗cpu情况

3.1.1指定cpu

将某个正在运行,或是开始运行时就可以指定cpu

taskset(需安装schedutils)  

// 代码出出Linux CPU affinity: http://blog.csdn.net/yfkiss/article/details/7464968
//test.c
#include<stdio.h>
void main(int argc, char** argv)
{
    int i=0;
   for(i=0;i<100000000;i++)
      {
          if(i==10000)
   {
      i=0;
           printf("program is running!\n");
   }
      }
 
}

两种设置方法  

taskset -c 0 ./test      test为程序名

Tastset -cp 0 pid       pid为进程号

 

  图片中的数据看,虚拟机(程序运行在虚拟机中的linux系统中)中的cpu0确实

最繁忙 ,但cpu1 cpu2 sys(内核态占用的cpu)仍然较高,并且从宿主机的cpu占用情况看,虚拟机中的3cpu感觉都快满了。这一结果与网友的一篇博客不符合:

 Linux CPU affinity  http://blog.csdn.net/yfkiss/article/details/7464968

 

现在我们换一种程序的写法:

//test.c
#include<stdio.h>
void main(int argc, char** argv)
{
    int i=0;
   for(i=0;i<100000000;i++)
      {
          if(i==10000)
   {
      i=0;
          //printf("program is running!\n");将打印信息注注释掉,
   }
      }
 
}


 

我们再来看cpu占用情况:

 

 

 这个结果才是我们想要的,对吧。我猜想是不是taskset不能控制内核进程的占用cpu情况,对于有打印的那个test.c,会引起内核线程的调用,导致三个cpu都有较高的使用率。

   我以目前的知识做出猜测:Printf最终会产生80h中断,系统调用,就是内核态,所以在消耗的cpu中,usr,sys各占一部分,而内核态对cpu的占用,我们使用taskset是无法控制的。反之,没有printf的就没有sys消耗了,我们就能控制只占用一个cpuusr部分

   此外,我也做过小实验,用test去调用另外的进程(自己写的,会占用3个cpu的usr 100%),当我控制test只在一个cpu上运行时,所调用的能跑满3个cpu的进程,也就只在一个cpu上运行。

 

3.1.2不指定cpu

 对与没有打印语句的test.c

./test  结果: 与指定cpu的情况一致,也是占用一个cpu 100 usr  0 sys

 

 对有打印语句的test.c

./test  结果: 与指定cpu的情况一致,也是占用一个cpu 75 usr  25 sys

6.1usr  45sys   4usr  61 sys

 

3.2多线程进程消耗cpu情况

#include<stdio.h>
#include<pthread.h>
 
void thr_fn1(void *arg)
{
int j=0;
   for(j=0;j<100000000;j++)
      {
          if(j==10000)
   {
      j=0;
      printf("program is running %d!\n",j);
   }
      }
}
 
void thr_fn2(void *arg)
{
int k=0;
   for(k=0;k<100000000;k++)
      {
          if(k==10000)
   {
      k=0;
      printf("program is running %d!\n",k);
   }
      }
}
 
void main(int argc, char** argv)
{
   int i=0;
   
   err=pthread_create(&ntid,NULL,thr_fn1,NULL);
   if(err!=0)
   {
   printf("cannot create thread");
   exit(1);
   }
 
   err=pthread_create(&ntid,NULL,thr_fn2,NULL);
   if(err!=0)
   {
   printf("cannot create thread");
   exit(1);
   }
   
   for(i=0;i<100000000;i++)
      {
          if(i==10000)
   {
      i=0;
      printf("program is running!\n");
   }
      }
 
}

3.2.1指定cpu

  不打印语句:如果指定cpu  ,则只有一个cpu满负载,其它两个cpu比较悠闲,且其它两个cpusys占用也很低

   打印语句: 如果指定cpu,  一个全部满载,另外两个的usr会比较空闲,但是sys占用率仍然高。

 

3.2.2不指定cpu

  不打印语句:如果不指定cpu,则三个cpu usr都会满负载。

  打印语句:如果不指定cpu,则三个都会满载,与单线程不同的是,每个cpu核的sys占用都较高

 

Ps: 具体的占用情况需呀读者自己去尝试,分析

   要让top输出某个特定进程<pid>并检查该进程内运行的线程状况:

$ top -H -p <pid>

  

四、在函数中显示的对线程绑定cpu

//代码出处: http://0987654321.blog.51cto.com/6934559/1409979
void *MyfunWithMultiThread(void *arg)
   {
       cpu_set_t mask;
       cpu_set_t get;
       int i = 0;
       int num = 0;
       int cpuID = *(int *)arg;
       CPU_ZERO(&mask);
       CPU_SET(2, &mask);
       if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {  //对线程的cpu addinity值进行调整,绑定到cpu2
           fprintf(stderr, "set thread affinity failed\n");
       }
       CPU_ZERO(&get);
       if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) {
           fprintf(stderr, "get thread affinity failed\n");
       }
       num = sysconf(_SC_NPROCESSORS_CONF);
       for (i = 0; i < num; i++) {
           if (CPU_ISSET(i, &get)) {
               printf("thread %d is running in processor %d\n", (int)pthread_self(), i);
               printf("Original setting is in processor  %d\n\n", cpuID);
           }
       }
       sleep(10);
   }

 

对于进程的绑定:

 int sched_setaffinity(pid_t pid, size_t cpusetsize, const cpu_set_t *mask);

 int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值