您的位置:首页 > 其它

关于CPU affinity的几篇文章

2016-10-22 15:38 330 查看
cpu绑定和cpu亲和性原文地址:http://blog.csdn.net/joker0910/article/details/7484371将进程/线程与cpu绑定,最直观的好处就是提高了cpu cache的命中率,从而减少内存访问损耗,提高程序的速度。我觉得在NUMA架构下,这个操作对系统运行速度的提升有较大的意义,而在SMP架构下,这个提升可能就比较小。这主要是因为两者对于cache、总线这些资源的分配使用方式不同造成的,NUMA每个cpu有自己的一套资源体系,
SMP中每个核心还是需要共享这些资源的,从这个角度来看,NUMA使用cpu绑定时,每个核心可以更专注地处理一件事情,资源体系被充分使用,减少了同步的损耗。SMP由于一部分资源的共享,在进行了绑定操作后,受到的影响还是很大的。通过linux提供的几个api, 可以轻松地完成这个优化:
下面是一个实例。[cpp] view
plain copy/** @FileName: simple_affinity.c* @Author: wzj* @Brief:* 1. cpu affinity. case* 2.在子线程中,会继承绑定的cpu..., 不过在子线程中,可以重新分配。** @History:**** @Date: 2012年04月21日星期六12:56:14**/#include <stdlib.h>#include <stdio.h>#include <unistd.h>#define __USE_GNU //启用CPU_ZERO等相关的宏//#define _GNU_SOURCE#include <sched.h>#include <pthread.h> //这个东西原来放在__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 1if(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 < num; i++){if(CPU_ISSET(i, &mask))printf("new thread %d run on processor %d\n", getpid(), i);}while(1);sleep (1);}} //while(1); //如果觉得不明显,改成这个,[cpp] view
plain copyvoid* 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 < num; i++){if(CPU_ISSET(i, &mask))printf("child thread %d run on processor %d\n", getpid(), i);}sleep (1);}}intmain(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 < num; i++){if(CPU_ISSET(i, &get)){printf("this process %d is runing on procesor:%d\n", getpid(), i);}}sleep(1);}//while(1); //使用这个更明显return 0;}编译:[cpp] view
plain copygcc -o cpu simple_affinity.c -lpthread执行./cpu [cpu num / masks] ,使用top观察cpu使用状况。 使用./cpu 0 时,可以发现,两颗核心使用率都比较高, 使用./cpu 1时,可以发现,1核的压力比较重。当然还可以对线程进行cpu绑定。[cpp] view
plain copy#define _GNU_SOURCE#include <pthread.h>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.htmlLinux中线程与CPU核的绑定原文地址:http://blog.chinaunix.net/uid-26739406-id-3181199.html
最近在对项目进行性能优化,由于在多核平台上,所以了解了些进程、线程绑定cpu核的问题,在这里将所学记录一下。不管是线程还是进程,都是通过设置亲和性(affinity)来达到目的。对于进程的情况,一般是使用sched_setaffinity这个函数来实现,网上讲的也比较多,这里主要讲一下线程的情况。与进程的情况相似,线程亲和性的设置和获取主要通过下面两个函数来实现:int pthread_setaffinity_np(pthread_tthread,
size_t cpusetsize,const
cpu_set_t *cpuset);int
pthread_getaffinity_np(pthread_t thread,
size_t cpusetsize,cpu_set_t
*cpuset);从函数名以及参数名都很明了,唯一需要点解释下的可能就是cpu_set_t这个结构体了。这个结构体的理解类似于select中的fd_set,可以理解为cpu集,也是通过约定好的宏来进行清除、设置以及判断://初始化,设为空void CPU_ZERO (cpu_set_t *set);//将某个cpu加入cpu集中void CPU_SET (int cpu, cpu_set_t
*set);//将某个cpu从cpu集中移出void CPU_CLR (int cpu, cpu_set_t *set);//判断某个cpu是否已在cpu集中设置了int CPU_ISSET (int cpu, const cpu_set_t *set);cpu集可以认为是一个掩码,每个设置的位都对应一个可以合法调度的 cpu,而未设置的位则对应一个不可调度的
CPU。换而言之,线程都被绑定了,只能在那些对应位被设置了的处理器上运行。通常,掩码中的所有位都被置位了,也就是可以在所有的cpu中调度。以下为测试代码:点击(此处)折叠或打开#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <pthread.h>#include <sched.h>void *myfun(void *arg){cpu_set_t mask;cpu_set_t get;char buf[256];int i;int j;int num = sysconf(_SC_NPROCESSORS_CONF);printf("system
has %d processor(s)\n", num);for (i = 0; i < num; i++) {CPU_ZERO(&mask);printf("mask=%x\n", mask);CPU_SET(i, &mask);printf("mask=%x\n", mask);if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {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");}for (j = 0; j < num; j++) {if (CPU_ISSET(j, &get)) {printf("thread
%d is running in processor %d\n", (int)pthread_self(), j);}}j = 0;while (j++ < 100000000) {memset(buf, 0, sizeof(buf));}}pthread_exit(NULL);}int main(int argc, char *argv[]){pthread_t tid;if (pthread_create(&tid, NULL, (void *)myfun, NULL) != 0) {fprintf(stderr, "thread
create failed\n");return -1;}pthread_join(tid, NULL);return 0;}这段代码将使myfun线程在所有cpu中依次执行一段时间,在我的四核cpu上,执行结果为 :system has 4 processor(s)thread 1095604544 is running in processor 0thread 1095604544 is running in processor 1thread 1095604544 is running in processor 2thread 1095604544 is running in processor 3在一些嵌入式设备中,运行的进程线程比较单一,如果指定进程线程运行于特定的cpu核,减少进程、线程的核间切换,有可能可以获得更高的性能。编译命令为:gcc cpu_affinity.c -lpthread -o cpu_affinity更直观地查看程序在CPU的affinity,top -d 1,然后再按下‘1’。可以看到Cpu1处于100%占用率。同时执行的log如下,从mask的值也可以看出当前附着在哪个CPU上面:system has 4 processor(s)mask=81a2ed00mask=1thread -2120026368 is running in processor 0mask=81a2ed00mask=2thread -2120026368 is running in processor 1mask=81a2ed00mask=4thread -2120026368 is running in processor 2mask=81a2ed00mask=8thread -2120026368 is running in processor 3


Linux中CPU亲和性(affinity)

原文地址:http://www.cnblogs.com/LubinLew/p/cpu_affinity.html?utm_source=tuicool&utm_medium=referral


0、准备知识

超线程技术(Hyper-Threading):就是利用特殊的硬件指令,把两个逻辑内核(CPU core)模拟成两个物理芯片,    让单个处理器都能使用线程级并行计算,进而兼容多线程操作系统和软件,减少了CPU的闲置时间,提高的CPU的运行效率。    我们常听到的双核四线程/四核八线程指的就是支持超线程技术的CPU.物理CPU:机器上安装的实际CPU, 比如说你的主板上安装了一个8核CPU,那么物理CPU个数就是1个,所以物理CPU个数就是主板上安装的CPU个数。逻辑CPU:一般情况,我们认为一颗CPU可以有多核,加上intel的超线程技术(HT), 可以在逻辑上再分一倍数量的CPU core出来;
逻辑CPU数量 = 物理CPU数量 x CPU cores x 2(如果支持并开启HT) //前提是CPU的型号一致,如果不一致只能一个一个的加起来,不用直接乘以物理CPU数量
//比如你的电脑安装了一块4核CPU,并且支持且开启了超线程(HT)技术,那么逻辑CPU数量 = 1 × 4 × 2 = 8
Linux下查看CPU相关信息, CPU的信息主要都在/proc/cupinfo中,
# 查看物理CPU个数
cat /proc/cpuinfo|grep "physical id"|sort|uniq|wc -l# 查看每个物理CPU中core的个数(即核数)
cat /proc/cpuinfo|grep "cpu cores"|uniq# 查看逻辑CPU的个数
cat /proc/cpuinfo|grep "processor"|wc -l# 查看CPU的名称型号
cat /proc/cpuinfo|grep "name"|cut -f2 -d:|uniq
Linux查看某个进程运行在哪个逻辑CPU上
ps -eo pid,args,psr
#参数的含义:
pid - 进程ID
args - 该进程执行时传入的命令行参数
psr - 分配给进程的逻辑CPU例子:
[~]# ps -eo pid,args,psr | grep nginx
9073 nginx: master process /usr/ 1
9074 nginx: worker process 0
9075 nginx: worker process 1
9076 nginx: worker process 2
9077 nginx: worker process 3
13857 grep nginx 3
Linux查看线程的TIDTID就是Thread ID,他和POSIX中pthread_t表示的线程ID完全不是同一个东西.Linux中的POSIX线程库实现的线程其实也是一个轻量级进程(LWP),这个TID就是这个线程的真实PID.但是又不能通过getpid()函数获取,Linux中定义了gettid()这个接口,但是通常都是未实现的,所以需要使用下面的方式获取TID。
//program
#include <sys/syscall.h>
pid_t tid;
tid = syscall(__NR_gettid);// or syscall(SYS_gettid)//command-line
(1)ps -efL | grep prog_name
(2)ls /proc/pid/task //文件夹名即TID



1、CPU亲和性(亲和力)


1.1 基本概念

CPU affinity 是一种调度属性(scheduler property), 它可以将一个进程"绑定" 到一个或一组CPU上.在SMP(Symmetric Multi-Processing对称多处理)架构下,Linux调度器(scheduler)会根据CPU affinity的设置让指定的进程运行在"绑定"的CPU上,而不会在别的CPU上运行.Linux调度器同样支持自然CPU亲和性(natural CPU affinity): 调度器会试图保持进程在相同的CPU上运行, 这意味着进程通常不会在处理器之间频繁迁移,进程迁移的频率小就意味着产生的负载小。因为程序的作者比调度器更了解程序,所以我们可以手动地为其分配CPU核,而不会过多地占用CPU0,或是让我们关键进程和一堆别的进程挤在一起,所有设置CPU亲和性可以使某些程序提高性能。


1.2 表示方法

CPU affinity 使用位掩码(bitmask)表示, 每一位都表示一个CPU, 置1表示"绑定".最低位表示第一个逻辑CPU, 最高位表示最后一个逻辑CPU.CPU affinity典型的表示方法是使用16进制,具体如下.
0x00000001
is processor #00x00000003
is processors #0 and #10xFFFFFFFF
is all processors (#0 through #31)


2、taskset命令

taskset命名用于获取或者设定CPU亲和性.
# 命令行形式
taskset [options] mask command [arg]...
taskset [options] -p [mask] pidPARAMETER
    mask : cpu亲和性,当没有-c选项时, 其值前无论有没有0x标记都是16进制的,
        当有-c选项时,其值是十进制的.
    command : 命令或者可执行程序
    arg : command的参数
    pid : 进程ID,可以通过ps/top/pidof等命令获取OPTIONS
    -a, --all-tasks (旧版本中没有这个选项)
        这个选项涉及到了linux中TID的概念,他会将一个进程中所有的TID都执行一次CPU亲和性设置.
        TID就是Thread ID,他和POSIX中pthread_t表示的线程ID完全不是同一个东西.
        Linux中的POSIX线程库实现的线程其实也是一个进程(LWP),这个TID就是这个线程的真实PID.
-p, --pid
操作已存在的PID,而不是加载一个新的程序
-c, --cpu-list
声明CPU的亲和力使用数字表示而不是用位掩码表示. 例如 0,5,7,9-11.
-h, --help
display usage information and exit
-V, --version
output version information and exit
USAGE    1) 使用指定的CPU亲和性运行一个新程序      taskset [-c] mask command [arg]...        举例:使用CPU0运行ls命令显示/etc/init.d下的所有内容          taskset -c 0 ls -al /etc/init.d/    2) 显示已经运行的进程的CPU亲和性      taskset -p pid        举例:查看init进程(PID=1)的CPU亲和性          taskset -p 1    3) 改变已经运行进程的CPU亲和力     taskset -p[c] mask pid        举例:打开2个终端,在第一个终端运行top命令,第二个终端中          首先运行:[~]# ps -eo pid,args,psr | grep top #获取top命令的pid和其所运行的CPU号          其次运行:[~]# taskset -cp 新的CPU号 pid #更改top命令运行的CPU号          最后运行:[~]# ps -eo pid,args,psr | grep top #查看是否更改成功PERMISSIONS一个用户要设定一个进程的CPU亲和性,如果目标进程是该用户的,则可以设置,如果是其他用户的,则会设置失败,提示 Operation not permitted.当然root用户没有任何限制.任何用户都可以获取任意一个进程的CPU亲和性.taskset命令其实就是使用sched_getaffinity()和sched_setaffinity()接口实现的,相信看完了第3节你也能自己实现一个taskset命令.有兴趣的可以看一下其源代码:ftp://ftp.kernel.org/pub/linux/utils/util-linux/vX.YZ/util-linux-X.YZ-xxx.tar.gz /schedutils/taskset.c


3、编程API

下面是用用于设置和获取CPU亲和性相关的API.
#define _GNU_SOURCE
#include <sched.h>
#include <pthread.h> //for pthread functions(last 4) 注意<pthread.h>包含<sched.h>/* MACRO */
/* The following macros are provided to operate on the CPU set set */
/* Clears set, so that it contains no CPUs */
void CPU_ZERO(cpu_set_t *set);
void CPU_ZERO_S(size_t setsize, cpu_set_t *set);/* Add CPU cpu to set */
void CPU_SET(int cpu, cpu_set_t *set);
void CPU_SET_S(int cpu, size_t setsize, cpu_set_t *set);/* Remove CPU cpu from set */
void CPU_CLR(int cpu, cpu_set_t *set);
void CPU_CLR_S(int cpu, size_t setsize, cpu_set_t *set);/* Test to see if CPU cpu is a member of set */
int CPU_ISSET(int cpu, cpu_set_t *set);
int CPU_ISSET_S(int cpu, size_t setsize, cpu_set_t *set);/* Return the number of CPUs in set */
void CPU_COUNT(cpu_set_t *set);
void CPU_COUNT_S(size_t setsize, cpu_set_t *set);/* The following macros perform logical operations on CPU sets */
/* Store the logical AND of the sets srcset1 and srcset2 in destset (which may be one of the source sets). */
void CPU_AND(cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_AND_S(size_t setsize, cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2);/* Store the logical OR of the sets srcset1 and srcset2 in destset (which may be one of the source sets). */
void CPU_OR(cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_OR_S(size_t setsize, cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2);/* Store the logical XOR of the sets srcset1 and srcset2 in destset (which may be one of the source sets). */
void CPU_XOR(cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2);
void CPU_XOR_S(size_t setsize, cpu_set_t *destset, cpu_set_t *srcset1, cpu_set_t *srcset2);/* Test whether two CPU set contain exactly the same CPUs. */
int CPU_EQUAL(cpu_set_t *set1, cpu_set_t *set2);
int CPU_EQUAL_S(size_t setsize, cpu_set_t *set1, cpu_set_t *set2);/* The following macros are used to allocate and deallocate CPU sets: */
/* Allocate a CPU set large enough to hold CPUs in the range 0 to num_cpus-1 */
cpu_set_t *CPU_ALLOC(int num_cpus);/* Return the size in bytes of the CPU set that would be needed to hold CPUs in the range 0 to num_cpus-1.
This macro provides the value that can be used for the setsize argument in the CPU_*_S() macros */
size_t CPU_ALLOC_SIZE(int num_cpus);/* Free a CPU set previously allocated by CPU_ALLOC(). */
void CPU_FREE(cpu_set_t *set);/* API */
/* Set the CPU affinity for a task */
int sched_setaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);
/* Get the CPU affinity for a task */
int sched_getaffinity(pid_t pid, size_t cpusetsize, cpu_set_t *mask);/* set CPU affinity attribute in thread attributes object */
int pthread_attr_setaffinity_np(pthread_attr_t *attr, size_t cpusetsize, const cpu_set_t *cpuset);
/* get CPU affinity attribute in thread attributes object */
int pthread_attr_getaffinity_np(const pthread_attr_t *attr, size_t cpusetsize, cpu_set_t *cpuset);/* set CPU affinity of a thread */
int pthread_setaffinity_np(pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset);
/* get CPU affinity of a thread */
int pthread_getaffinity_np(pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);
相关的宏通常都分为2种,一种是带_S后缀的,一种不是不带_S后缀的, 从声明上看带_S后缀的宏都多出一个参数 setsize.从功能上看他们的区别是带_S后缀的宏是用于操作动态申请的CPU set(s),所谓的动态申请其实就是使用宏 CPU_ALLOC 申请,参数setsize 可以是通过宏 CPU_ALLOC_SIZE 获得,两者的用法详见下面的例子.相关的API只有6个, 前2个是用来设置进程的CPU亲和性,需要注意的一点是,当这2个API的第一个参数pid为0时,表示使用调用进程的进程ID;后4个是用来设置线程的CPU亲和性。其实sched_setaffinity()也可以用来设置线程的CPU的亲和性,也就是taskset “-a”选项中提到的TID概念。


3.1 例子一:使用2种方式(带和不带_S后缀的宏)获取当前进程的CPU亲和性

#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h> /* sysconf */
#include <stdlib.h> /* exit */
#include <stdio.h>int main(void)
{
int i, nrcpus;
cpu_set_t mask;
unsigned long bitmask = 0;CPU_ZERO(&mask);/* Get the CPU affinity for a pid */
if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1)
{
perror("sched_getaffinity");
exit(EXIT_FAILURE);
}/* get logical cpu number */
nrcpus = sysconf(_SC_NPROCESSORS_CONF);for (i = 0; i < nrcpus; i++)
{
if (CPU_ISSET(i, &mask))
{
bitmask |= (unsigned long)0x01 << i;
printf("processor #%d is set\n", i);
}
}
printf("bitmask = %#lx\n", bitmask);exit(EXIT_SUCCESS);
}
/*----------------------------------------------------------------*/
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h> /* sysconf */
#include <stdlib.h> /* exit */
#include <stdio.h>int main(void)
{
int i, nrcpus;
cpu_set_t *pmask;
size_t cpusize;
unsigned long bitmask = 0;/* get logical cpu number */
nrcpus = sysconf(_SC_NPROCESSORS_CONF);pmask = CPU_ALLOC(nrcpus);
cpusize = CPU_ALLOC_SIZE(nrcpus);
CPU_ZERO_S(cpusize, pmask);/* Get the CPU affinity for a pid */
if (sched_getaffinity(0, cpusize, pmask) == -1)
{
perror("sched_getaffinity");
CPU_FREE(pmask);
exit(EXIT_FAILURE);
}
for (i = 0; i < nrcpus; i++)
{
if (CPU_ISSET_S(i, cpusize, pmask))
{
bitmask |= (unsigned long)0x01 << i;
printf("processor #%d is set\n", i);
}
}
printf("bitmask = %#lx\n", bitmask);CPU_FREE(pmask);
exit(EXIT_SUCCESS);
}
执行结果如下(4核CPU):
执行结果


3.2 例子二:设置进程的CPU亲和性后再获取显示CPU亲和性

#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h> /* sysconf */
#include <stdlib.h> /* exit */
#include <stdio.h>int main(void)
{
int i, nrcpus;
cpu_set_t mask;
unsigned long bitmask = 0;CPU_ZERO(&mask);CPU_SET(0, &mask); /* add CPU0 to cpu set */
CPU_SET(2, &mask); /* add CPU2 to cpu set *//* Set the CPU affinity for a pid */
if (sched_setaffinity(0, sizeof(cpu_set_t), &mask) == -1)
{
perror("sched_setaffinity");
exit(EXIT_FAILURE);
}CPU_ZERO(&mask);/* Get the CPU affinity for a pid */
if (sched_getaffinity(0, sizeof(cpu_set_t), &mask) == -1)
{
perror("sched_getaffinity");
exit(EXIT_FAILURE);
}/* get logical cpu number */
nrcpus = sysconf(_SC_NPROCESSORS_CONF);for (i = 0; i < nrcpus; i++)
{
if (CPU_ISSET(i, &mask))
{
bitmask |= (unsigned long)0x01 << i;
printf("processor #%d is set\n", i);
}
}
printf("bitmask = %#lx\n", bitmask);exit(EXIT_SUCCESS);
}


3.3 例子三:设置线程的CPU属性后再获取显示CPU亲和性

这个例子来源于Linux的man page.
#define _GNU_SOURCE
#include <pthread.h> //不用再包含<sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)int
main(int argc, char *argv[])
{
int s, j;
cpu_set_t cpuset;
pthread_t thread;thread = pthread_self();/* Set affinity mask to include CPUs 0 to 7 */
CPU_ZERO(&cpuset);
for (j = 0; j < 8; j++)
CPU_SET(j, &cpuset);s = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
if (s != 0)
{
handle_error_en(s, "pthread_setaffinity_np");
}/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(thread, sizeof(cpu_set_t), &cpuset);
if (s != 0)
{
handle_error_en(s, "pthread_getaffinity_np");
}printf("Set returned by pthread_getaffinity_np() contained:\n");
for (j = 0; j < CPU_SETSIZE; j++) //CPU_SETSIZE 是定义在<sched.h>中的宏,通常是1024
{
if (CPU_ISSET(j, &cpuset))
{
printf(" CPU %d\n", j);
}
}
exit(EXIT_SUCCESS);
}


3.4 例子四:使用seched_setaffinity设置线程的CPU亲和性

#define _GNU_SOURCE
#include <sched.h>
#include <stdlib.h>
#include <sys/syscall.h> // syscallint main(void)
{
pid_t tid;
int i, nrcpus;
cpu_set_t mask;
unsigned long bitmask = 0;CPU_ZERO(&mask);
CPU_SET(0, &mask); /* add CPU0 to cpu set */
CPU_SET(2, &mask); /* add CPU2 to cpu set */// get tid(线程的PID,线程是轻量级进程,所以其本质是一个进程)
tid = syscall(__NR_gettid); // or syscall(SYS_gettid);/* Set the CPU affinity for a pid */
if (sched_setaffinity(tid, sizeof(cpu_set_t), &mask) == -1)
{
perror("sched_setaffinity");
exit(EXIT_FAILURE);
}exit(EXIT_SUCCESS);
}
---------------------------------------------------------------------------------------------------------------------参考文献:
http://www.yboren.com/posts/44412.html?utm_source=tuicool http://www.ibm.com/developerworks/cn/linux/l-affinity.html http://saplingidea.iteye.com/blog/633616 http://blog.csdn.net/ttyttytty12/article/details/11726569 https://en.wikipedia.org/wiki/Processor_affinity http://blog.chinaunix.net/uid-23622436-id-3311579.html http://www.cnblogs.com/emanlee/p/3587571.html http://blog.chinaunix.net/uid-26651253-id-3342161.html http://blog.csdn.net/delphiwcdj/article/details/8476547 http://www.man7.org/linux/man-pages/man3/pthread_setaffinity_np.3.html http://www.man7.org/linux/man-pages/man3/pthread_attr_setaffinity_np.3.html
man CPU_SET taskset


管理处理器的亲和性(affinity)

原文地址:http://www.ibm.com/developerworks/cn/linux/l-affinity.html#download
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: