|
In order for the program to have a better performance, sometimes you need to process or thread is bound to a specific CPU, thus reducing the overhead of scheduling and protect critical processes or threads.
Process bound to CPU
Linux provides an interface, the process can be bound to a specific CPU:
#include < sched.h>
int sched_setaffinity (pid_t pid, size_t cpusetsize, const cpu_set_t * mask);
int sched_getaffinity (pid_t pid, size_t cpusetsize, cpu_set_t * mask);
parameter
pid: id number process If pid is 0, it indicates that this process
cpusetsize: mask size
mask: running processes CPU, the following functions can be operated by mask
#define CPU_SET (cpu, cpusetp) // set cpu
#define CPU_CLR (cpu, cpusetp) // delete cpu
#define CPU_ISSET (cpu, cpusetp) // determine cpu
#define CPU_ZERO (cpusetp) // initialized to 0
Sample Code
#include < stdio.h>
#include < unistd.h>
#include < math.h>
#include < sched.h>
void WasteTime ()
{
int abc = 10000000;
while (abc--)
{
int tmp = 10000 * 10000;
}
sleep (1);
}
int main (int argc, char ** argv)
{
cpu_set_t mask;
while (1)
{
CPU_ZERO (& mask);
CPU_SET (0, & mask);
if (sched_setaffinity (0, sizeof (mask), & mask) < 0) {
perror ( "sched_setaffinity");
}
WasteTime ();
CPU_ZERO (& mask);
CPU_SET (1, & mask);
if (sched_setaffinity (0, sizeof (mask), & mask) < 0) {
perror ( "sched_setaffinity");
}
WasteTime ();
CPU_ZERO (& mask);
CPU_SET (2, & mask);
if (sched_setaffinity (0, sizeof (mask), & mask) < 0) {
perror ( "sched_setaffinity");
}
WasteTime ();
CPU_ZERO (& mask);
CPU_SET (3, & mask);
if (sched_setaffinity (0, sizeof (mask), & mask) < 0) {
perror ( "sched_setaffinity");
}
WasteTime ();
}
}
test
After compiling the program, enter the command top -p process id, enter f, input j, press enter, you can see the process of constantly switching between cpu0123.
Threads are bound to CPU
Not only the process can be bound to a CPU, the thread can be. Linux provides an interface threads can be bound to a specific CPU:
#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);
The interface with the process is bound to use interface CPU basically the same.
When the process is bound to a specific CPU, the thread can still bind to other CPU, there is no conflict.
Sample Code
#include < stdio.h>
#include < math.h>
#include < pthread.h>
#include < unistd.h>
#include < sched.h>
void WasteTime ()
{
int abc = 10000000;
while (abc--)
{
int tmp = 10000 * 10000;
}
sleep (1);
}
void * thread_func (void * param)
{
cpu_set_t mask;
while (1)
{
CPU_ZERO (& mask);
CPU_SET (1, & mask);
if (pthread_setaffinity_np (pthread_self (), sizeof (mask),
& Mask) < 0) {
perror ( "pthread_setaffinity_np");
}
WasteTime ();
CPU_ZERO (& mask);
CPU_SET (2, & mask);
if (pthread_setaffinity_np (pthread_self (), sizeof (mask),
& Mask) < 0) {
perror ( "pthread_setaffinity_np");
}
WasteTime ();
}
}
void * thread_func1 (void * param)
{
cpu_set_t mask;
while (1)
{
CPU_ZERO (& mask);
CPU_SET (3, & mask);
if (pthread_setaffinity_np (pthread_self (), sizeof (mask),
& Mask) < 0) {
perror ( "pthread_setaffinity_np");
}
WasteTime ();
CPU_ZERO (& mask);
CPU_SET (4, & mask);
if (pthread_setaffinity_np (pthread_self (), sizeof (mask),
& Mask) < 0) {
perror ( "pthread_setaffinity_np");
}
WasteTime ();
}
}
int main (int argc, char * argv [])
{
cpu_set_t mask;
CPU_ZERO (& mask);
CPU_SET (0, & mask);
if (sched_setaffinity (0, sizeof (mask), & mask) < 0) {
perror ( "sched_setaffinity");
}
pthread_t my_thread;
if (pthread_create (& my_thread, NULL, thread_func,
NULL)! = 0) {
perror ( "pthread_create");
}
if (pthread_create (& my_thread, NULL, thread_func1,
NULL)! = 0) {
perror ( "pthread_create");
}
while (1) {WasteTime ();}
pthread_exit (NULL);
}
test
After compiling Run, type command top -p process id, enter f, input j, press enter, enter H, you can see the main thread has remained at cpu0, a thread before cpu12 switch, switch to another thread between cpu34 . |
|
|
|