CPU affinity in Linux (affinity)

Source: Internet
Author: User
Tags bitmask posix set set

0. Prepare knowledge

Hyper-Threading Technology (hyper-threading): Using special hardware instructions, the two logical cores (CPU core) are simulated into two physical chips,

Allows a single processor to use thread-level parallel computing, which is compatible with multi-threaded operating systems and software, reducing the idle time of the CPU and improving the efficiency of CPU operation.

The two-core four thread/four-core eight thread that we often hear refers to CPUs that support hyper-Threading technology.

Physical CPU: The actual CPU installed on the machine, such as your motherboard installed a 8-core CPU, then the number of physical CPUs is one, so the number of physical CPUs is the number of CPUs installed on the motherboard.

Logical CPU: In general, we think that a CPU can have multicore, plus Intel's Hyper-Threading Technology (HT), can logically divide the number of CPU core out;

Number of logical CPUs = number of physical CPUs x CPU cores x 2 (if HT is supported and turned on)//If the CPU model is the same, if the inconsistency can only be added together one by one, not directly multiplied by the number of physical CPUs//For example, your computer installed a 4-core CPU, and Hyper-Threading (HT) technology is supported and turned on, the number of logical CPUs = 1X4X2 = 8

Linux to view CPU-related information , CPU information is mainly in the/proc/cupinfo,

# View the number of physical CPUs Cat/proc/cpuinfo|grep "Physical ID" |sort|uniq|wc-l# see the number of cores in each physical CPU (that is, the number of nuclei) Cat/proc/cpuinfo|grep "CPU Cores "|uniq# View the number of logical CPUs Cat/proc/cpuinfo|grep" Processor "|wc-l# view the name of the CPU model CAT/PROC/CPUINFO|GREP" name "|cut-f2-d:| Uniq

Linux to see which logical CPU a process is running on

Ps-eo PID,ARGS,PSR
#参数的含义: PID -Process Idargs-the command-line parameter passed in when the process executes PSR -logical CPU assigned to the process

Example:
[~]# 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 View Thread's TID

The TID is the thread ID, which is not exactly the same thing as the threading ID that pthread_t in POSIX.

The thread implemented by the POSIX line libraries in Linux is actually a lightweight process (LWP), which is the true PID of this thread.

But it cannot be obtained through the getpid () function, which defines the Gettid () interface in Linux, but is usually not implemented, so it is necessary to obtain the TID in the following way.

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            //folder name is Tid

1, CPU affinity (Affinity) 1.1 Basic concepts

CPU affinity is a scheduling attribute (scheduler property) that can "bind" a process to one or a set of CPUs.

Under the SMP (symmetric multi-processing symmetric multi-processing) architecture, the Linux Scheduler (Scheduler) allows the specified process to run on the "bound" CPU based on the settings of the CPU affinity, rather than running on another CPU.

The Linux scheduler also supports natural CPU affinity (Natural CPU Affinity): The scheduler tries to keep the process running on the same CPU, which means that the process usually does not migrate frequently between processors, and the low frequency of process migrations means that the resulting load is small.

Because the author of the program knows the program better than the scheduler, we can manually assign it a CPU core without too much CPU0, or let our critical processes and a bunch of other processes squeeze together, and all of the CPU affinity settings can improve performance for some programs.

1.2 Presentation method

CPU Affinity uses a bitmask (bitmask) to indicate that each bit represents a CPU, and 1 indicates "binding."

The lowest bit represents the first logical CPU, and the highest bit represents the last logical CPU.

The typical representation of CPU affinity is to use 16 binary, as described below.

0X00000001 is    processor #00x00000003 is    processors #0 and #10xFFFFFFFF are all    processors (#0 through #31)
2. Taskset command

The Taskset name is used to obtain or set CPU affinity.

# command line Form Taskset [options] Mask command [ARG] ...
Taskset [Options]-P [mask] pid

PARAMETER
 
MASK:CPU Affinity, when there is no-c option, its value before whether or not the 0x tag is 16 binary,
When the-C option is available, its value is decimal.
Command: Commands or executable programs
Parameters of the Arg:command
PID: Process ID, can be obtained through commands such as Ps/top/pidof
OPTIONS
    
-A,--all-tasks (this option is not available in the previous version)
This option involves the concept of TID in Linux, which performs a CPU affinity setting for all of the TID in a process.
The TID is the thread ID, which is not exactly the same thing as the threading ID that pthread_t in POSIX.
The thread implemented by the POSIX line libraries in Linux is actually a process (LWP), which is the true PID of this thread. -P,--pid operation already exists PID, instead of loading a new program- C,--cpu-list declares that the affinity of the CPU is represented by a number instead of a bitmask. For example 0,5,7,9-11. -H,--help display usage information and exit-V,--version output version information and exit

USAGE

1) Run a new program with the specified CPU affinity

      Taskset [-c] Mask command [ARG] ...

Example: Using CPU0 to run the LS command to display all content under/ETC/INIT.D

          Taskset-c 0 ls-al/etc/init.d/

2) Show CPU affinity for processes that are already running

      Taskset-p PID

Example: Viewing the CPU affinity of the init process (pid=1)

          Taskset-p 1

3) Change the CPU affinity of the already running process

Taskset-p[c] Mask pid

Example: Open 2 terminals, run the top command at the first terminal, and the second terminal

First run: [~]# ps-eo pid,args,psr | grep top #获取top命令的pid和其所运行的CPU号

Next run: [~]# TASKSET-CP new CPU number PID #更改top命令运行的CPU号

Last run: [~]# ps-eo pid,args,psr | grep top #查看是否更改成功

PERMISSIONS
A user to set the CPU affinity of a process, if the target process is the user's, you can set, if it is other users, it will be set to fail, prompting operation not permitted. Of course, the root user does not have any restrictions.

Any user can obtain the CPU affinity of any one process.

The Taskset command is actually implemented using the sched_getaffinity () and sched_setaffinity () interfaces, believing that you can implement a taskset command on your own after reading the 3rd section.

Interested can look at its source code: ftp://ftp.kernel.org/pub/linux/utils/util-linux/vX.YZ/util-linux-X.YZ-xxx.tar.gz/schedutils/ Taskset.c

3. Programming API

The following APIs are used to set up and get CPU affinity.

#define _gnu_source#include <sched.h> #include <pthread.h>//for pthread functions (last 4) Note <pthread.h  > contains <sched.h>/* MACRO */* The following macros is 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 the 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 SRCSE T1 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 could 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 could 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 the 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 is 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 is needed to hold CPUs in the range 0 to num_cpus-1. This macro provides the value of the can is used for the setsize argument in the cpu_*_s () macros */size_t Cpu_allo                c_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 *CPU    Set); /* Get CPU affinity of a thread */int pthread_getaffinity_np (pthread_t thread, size_t cpusetsize, cpu_set_t *cpuset);

The related macros are usually divided into 2 kinds, one is with _s suffix, one is not without _s suffix, from the declaration to see the _s suffix macros are more than one parameter setsize.

Functionally, the difference is that the macro with the _s suffix is the CPU set (s) used to operate the dynamic request, and the so-called dynamic application is actually using the macro cpu_alloc application,

Parameter setsize can be obtained by macro cpu_alloc_size , both of which are described in the following example.

The related API is only 6, the first 2 is used to set the CPU affinity of the process, one thing to note is that when the first parameter of the 2 API PID is 0 o'clock, the process ID of the calling process is used;

The latter 4 are used to set the CPU affinity of the thread. In fact sched_setaffinity () can also be used to set the CPU affinity of the thread, that is, the TID concept mentioned in the Taskset "-a" option.

3.1 Example one: Use 2 ways (macros with and without _s suffix) to get CPU affinity for the current process
#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) {Perr        or ("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) 0x0            1 << 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 &LT;STDIO.H&GT; 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_getaffi        Nity ");        Cpu_free (Pmask);    Exit (Exit_failure); } for (i = 0; i < Nrcpus; i++) {if (cpu_isset_s (i, Cpusize, Pmask)) {Bitmask |= (Unsi            gned long) 0x01 << i;         printf ("Processor #%d is set\n", i);          }} printf ("bitmask =% #lx \ n", bitmask);    Cpu_free (Pmask); Exit (exit_success);}

The execution results are as follows (4 cores CPU):

Execution Results

3.2 Example Two: Set the CPU affinity of the process before getting the display CPU affinity
#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), &ma        SK) = =-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) {Perr        or ("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) 0x0            1 << i; printf ("Processor #%d is set\n ", i);    }} printf ("bitmask =% #lx \ n", bitmask); Exit (exit_success);}

3.3 Example Three: Set the CPU properties of a thread before getting the display CPU affinity

This example comes from the man page of Linux.

#define _gnu_source#include <pthread.h>/No <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);} W    Hile (0) intmain (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_setsizeis a macro defined in <sched.h>, usually the cpu_isset {if (j, &cpuset)) {printf ("CPU%d\n", j); }} exit (Exit_success);}

3.4 Example four: Using Seched_setaffinity to set the CPU affinity of a thread
#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 (thread pid, thread is lightweight process, so its essence is a process) C10/>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)     {        Perr or ("sched_setaffinity");        Exit (exit_failure);    }        Exit (exit_success);}

--------------------------------------------------------------------------------------------------------------- ------

Reference documents:

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

Mans Cpu_set Taskset

CPU affinity in Linux (affinity)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.