The most intuitive benefit of binding processes/threads to CPUs is to increase the hit rate of the CPU cache, thereby reducing memory access loss and increasing the speed of the program. I think that under the NUMA architecture, this operation has a significant impact on the speed of the system, and in the SMP architecture the promotion may be relatively small. This is mainly because both the cache, bus, the allocation of these resources are different, NUMA each CPU has its own set of resource system, SMP in each core or need to share these resources, from this point of view, NUMA use CPU binding timing, Each core can be more focused on one thing, the resource system is fully used, reducing the loss of synchronization. Because of the sharing of some resources, SMP has been greatly affected after the binding operation.
With several APIs from Linux, this optimization can be done easily:
#define _gnu_source
#include <sched.h>
int sched_setaffinity (pid_t pid, size_t cpusetsize,cpu_set_t * mask); Set PID-bound CPU,
int sched_getaffinity (pid_t pid, size_t cpusetsize,cpu_set_t *mask); View the PID-bound CPU.
cpu_set_t //is a mask array, a total of 1024 bits, each of which can correspond to a CPU core
//The following macros, all of which operate on this mask. If necessary, a process can be bound to multiple CPUs.
void Cpu_zero (cpu_set_t *set);
void Cpu_set (int CPU, cpu_set_t *set);
void cpu_clr (int CPU, cpu_set_t *set);
int cpu_isset (int CPU, cpu_set_t *set);
Here is an example.
* * @FileName: SIMPLE_AFFINITY.C * @Author: WZJ * @Brief: * 1. CPU affinity.
Case * 2. In child threads, the bound CPUs are inherited ..., but in child threads, you can reassign them. * * @History: * * * * * @Date: April 21, 2012 12:56:14 * * * * * * * * * * * * #include <stdlib.h> #include <stdio.h>
; #include <unistd.h> #define __USE_GNU//Cpu_zero macros//#define _gnu_source #include <sched.h> #include &l T;pthread.h>//This thing was previously placed in __use_gnu macros, the results were reported by the compiler Cpu_zero undefined void* new_test_thread (void* arg) {cpu_set_t mask
;
int i = 0; int num = sysconf (_sc_nprocessors_conf);
Gets the current total number of CPUs Pthread_detach (Pthread_self ());
Cpu_zero (&mask); Cpu_set (1, &mask);
The Binding CPU 1 if (sched_setaffinity (0, sizeof (mask), &mask) = = 1)//0 represents the setting of the current thread/process.
{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); If it doesn't feel obvious, change it,
void* 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 ' processor%d\n ', get
PID (), i);
Sleep (1);
int main (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 are runing on procesor:
%d\n ", Getpid (), i);
} sleep (1); }//while (1);
Use this more visibly return 0; }
Compile:
Gcc-o CPU Simple_affinity.c-lpthread
Perform./cpu [CPU Num/masks], use top to observe CPU usage. Using./cpu 0 o'clock, you can find that the two core utilization rates are relatively high, use./cpu 1 o'clock, 1 nuclear pressure is relatively heavy.
Of course, you can also do CPU binding to threads.
#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);
This introduces the use of the time, more classic: http://www.ibm.com/developerworks/cn/linux/l-affinity.html