CPU Affinity

CPU亲和性是linux 2.6后出现的新功能,在多核环境下,能将进程或线程绑定到指定的CPU上,减少多进程或线程切换引起处理器的频繁迁移带来的性能损耗。

DPDK是Intel提供的高性能网络包采集库,能支持千兆万兆网卡数据采集,原因是其实现用到了CPU affinity,大内存管理,环形缓冲区等技术。将采集线程绑定不同的CPU上,避免线程在不同核上的切换,提高采集效率。

 

一. 测试

taskset 命令获取和设置cpu亲和性。

tasket -pc 0 1234  将pid为1234的进程绑定到cpu0上,top命令下输入1查看各cpu核心的内存占用情况

 

二. cpu affinity调度函数

1.1 进程调度

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

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

 

2.1 线程调度

int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, onst cpu_set_t *cpuset);

int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);

 

cpu_set_t 参数指定cpu掩码,通过下面几组函数设置:

CPU_ZERO(&cpuset) // 清空掩码

CPU_SET(1,&cpuset)  // 设置cpu1

 

三.测试

3.1 线程

#include <unistd.h> // sysconf
#include <stdio.h>

#define __USE_GNU // CPU_ZERO,CPU_SET使用需引入该宏
#include <pthread.h>

void *fun( void *arg );
void test_thread_affnity();

static int ncpus;

int main(int arg,char **argv)
{
	// 获取cpu核心数
	 ncpus = sysconf(_SC_NPROCESSORS_CONF);
	 printf("cpus:%d\n",ncpus);

	 // 测试线程绑定
	 test_thread_affnity();

	 pause();
	 return 0;
}


// 将耗时任务绑定至cpu0上
void *fun( void *arg )
{ 
	 int i = 1;

	 // attach to cpu0
	 cpu_set_t cpuset;
	 CPU_ZERO( &cpuset );
	 CPU_SET( 0%ncpus,&cpuset );

	 // set thread affinity
	 pthread_setaffinity_np( pthread_self(),sizeof(cpuset),&cpuset );

	 // 死循环
	 while(1)
	 {
	  if(i%10000000000 == 0)
	  {
		  printf("th-%u:I'm busying\n",pthread_self());
		  i = 0;
	  }

	  i++;
	 }

	return (void*)NULL;
}

void test_thread_affnity()
{
	 int i = 0;
	 pthread_t tid;
		
	 for( i=0;i<2;i++ )
	 {
		pthread_create( &tid,NULL,fun,NULL ); 
	 }
}

 

3.2 进程 

// 测试进程绑定
void test_process_affnity()
{
	pid_t pid = fork();

	if( pid == 0 )
	{
		cpu_set_t cpuset;
		CPU_ZERO(&cpuset);
		CPU_SET( 0%ncpus,&cpuset );

		// 将子进程绑定至cpu0
		sched_setaffinity( getpid(),sizeof(cpuset),&cpuset );

		waste_time();  // 干活中 ...
	}else
	{
		printf("father do nothing\n");
	} 
}

 

 

你可能感兴趣的:(dpdk,cpu affinity)