CPU affinity refers to the ability to bind one or more processes to one or more processors on a Linux system. The CPU affinity mask for a process determines which CPU or CPUs the process will run on. In a multiprocessor system, a mask that sets the affinity of the CPU may achieve better performance.
A CPU affinity mask uses a cpu_set_t struct to represent a collection of CPUs, and several of the following macros operate on the mask set individually: • Cpu_zero () clears a collection · Cpu_set () and CPU_CLR () each add a given CPU number to a set or remove it from a collection. · Cpu_isset () checks if a CPU number is in this collection.
The following two functions are used to set the get thread CPU affinity State:
sched_setaffinity (pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
This function sets the process to PID and lets it run on the CPU set by mask. If the PID has a value of 0, it indicates that the current process is specified. Causes the current process to run on those CPUs set by mask. The second parameter, Cpusetsize, is the length of the number specified by mask. Usually set to sizeof (cpu_set_t). If the process specified by the current PID is not running at this time on any of the CPUs specified by mask, the specified process will be migrated from the other CPU to the specified CPU on mask.
sched_getaffinity (pid_t pid, unsigned int cpusetsize, cpu_set_t *mask)
The function obtains the CPU bit mask of the process indicated by the PID and returns the mask to the structure that the mask points to. That is, which CPUs the specified PID can currently run on. Similarly, if the PID has a value of 0. Also indicates that the current process
- definition of cpu_set_t
- # Define __cpu_setsize 1024x768
- # Define __ncpubits (8 * sizeof (__CPU_MASK))
- typedef unsigned long int __cpu_mask;
- # define __cpuelt (CPU) (CPU)/__ncpubits
- # define __cpumask (CPU) ((__cpu_mask) 1 << ((CPU)% __ncpubits))
- typedef struct
- {
- __cpu_mask __bits[__cpu_setsize/__ncpubits];
- } cpu_set_t;
- # define __cpu_zero (CPUSETP) \
- Do {\
- unsigned int __i; \
- cpu_set_t *__arr = (CPUSETP); \
- For (__i = 0; __i < sizeof (cpu_set_t)/sizeof (__cpu_mask); ++__i) \
- __arr->__bits[__i] = 0; \
- } while (0)
- # define __cpu_set (CPU, cpusetp) \
- ((CPUSETP)->__bits[__cpuelt (CPU)] |= __cpumask (CPU))
- # define __CPU_CLR (CPU, cpusetp) \
- ((CPUSETP)->__bits[__cpuelt (CPU)] &= ~__cpumask (CPU))
- # define __cpu_isset (CPU, cpusetp) \
- (((CPUSETP)->__bits[__cpuelt (CPU)] & __cpumask (CPU))! = 0)
Test code:
- #include<stdlib.h>
- #include<stdio.h>
- #include<sys/types.h>
- #include<sys/sysinfo.h>
- #include<unistd.h>
- #define __USE_GNU
- #include<sched.h>
- #include<ctype.h>
- #include<string.h>
- #include<pthread.h>
- #Define Thread_max_num //1 CPUs up to the maximum number of processes
- int num=0; number of cores in//cpu
- void* threadfun(void* Arg) //arg pass thread designator (self-defined)
- {
- cpu_set_t Mask; the collection of//cpu nuclei
- cpu_set_t get; //Gets the CPU in the collection
- int *a = (int *) arg;
- printf ("The A is:%d\n", *a); //Display is the first few threads
- Cpu_zero (&mask); //Empty
- Cpu_set (*a,&mask); //Set affinity value
- if (sched_setaffinity (0, sizeof (mask), &mask) = = -1)//Set Thread CPU affinity
- {
- printf ("warning:could not set CPU affinity, continuing...\n");
- }
- While (1)
- {
- Cpu_zero (&get);
- if (sched_getaffinity (0, sizeof (GET), &get) = = -1)//Get thread CPU affinity
- {
- printf ("Warning:cound not get thread affinity, continuing...\n");
- }
- int i;
- For (i = 0; i < num; i++)
- {
- if (Cpu_isset (i, &get))//Determine which CPU the thread is affinity with
- {
- printf ("This thread%d is running processor:%d\n", i,i);
- }
- }
- }
- return NULL;
- }
- int main(int argc, char* argv[])
- {
- num = sysconf (_sc_nprocessors_conf); //Get the number of cores
- pthread_t Thread[thread_max_num];
- printf ("System has%i processor (s). \ n ", num);
- int tid[thread_max_num];
- int i;
- For (i=0;i<num;i++)
- {
- Tid[i] = i; //Each thread must have a tid[i]
- Pthread_create (&thread[0],null,threadfun, (void*) &tid[i]);
- }
- For (i=0; i< num; i++)
- {
- Pthread_join (Thread[i],NULL); Wait for all threads to end, thread is dead loop so Ctrl + C ends
- }
- return 0;
- }
Compile command: gcc bind.c-o bind-lpthread
Execution:./bind
Output result: slightly
Special attention:
#define __USE_GNU Don't write a # define _use_gnu
#include <pthread.h> must be written after the # define __USE_GNU, or the compilation will error
View your thread condition you can use top-h in another window to view the threads at execution time, and view the situation on each core using the top command and then the number "1".
Thread-bound CPU core-sched_setaffinity