How to set processor proximity to a specific pthread?

I would like to indicate the cpu affinity of a particular pthread. All the links I have found so far relate to setting the cpu affinity of the process (pid_t) and not the thread (pthread_t). I tried some experiments going through pthread_t and, as expected, they fail. Am I trying to do something impossible? If not, can you send a pointer, please? Thanks a million.

+52
multithreading cpu processor affinity
Sep 10 '09 at 21:19
source share
5 answers

This is a wrapper that I made to make my life easier. Its effect is that the calling thread is stuck in the kernel with id core_id :

 // core_id = 0, 1, ... n-1, where n is the system number of cores int stick_this_thread_to_core(int core_id) { int num_cores = sysconf(_SC_NPROCESSORS_ONLN); if (core_id < 0 || core_id >= num_cores) return EINVAL; cpu_set_t cpuset; CPU_ZERO(&cpuset); CPU_SET(core_id, &cpuset); pthread_t current_thread = pthread_self(); return pthread_setaffinity_np(current_thread, sizeof(cpu_set_t), &cpuset); } 
+46
Jul 20 2018-12-12T00:
source share

Assuming linux:

Interface for setting affinity - as you probably already discovered:

 int sched_setaffinity(pid_t pid,size_t cpusetsize,cpu_set_t *mask); 

Passing 0 as pid, and it will only apply to the current thread, or another thread reports its pid core with a specific linux call pid_t gettid (void); and pass this as pid.

Quote reference page

A proximity mask is a per-thread attribute that can be configured independently for each thread in a thread group. The value returned from the call gettid (2) can be passed in the pid argument. Specifying pid as 0 sets the attribute for the calling thread, and passing the value obtained by calling to getpid (2) sets the attribute for the main thread of the thread group. (If you are using the POSIX thread API, then use pthread_setaffinity_np (3) instead of sched_setaffinity ().)

+38
Sep 10 '09 at 21:34
source share
 //compilation: gcc -o affinity affinity.c -lpthread #define _GNU_SOURCE #include <sched.h> //cpu_set_t , CPU_SET #include <pthread.h> //pthread_t #include <stdio.h> void *th_func(void * arg); int main(void) { pthread_t thread; //the thread pthread_create(&thread,NULL,th_func,NULL); pthread_join(thread,NULL); return 0; } void *th_func(void * arg) { //we can set one or more bits here, each one representing a single CPU cpu_set_t cpuset; //the CPU we whant to use int cpu = 2; CPU_ZERO(&cpuset); //clears the cpuset CPU_SET( cpu , &cpuset); //set CPU 2 on cpuset /* * cpu affinity for the calling thread * first parameter is the pid, 0 = calling thread * second parameter is the size of your cpuset * third param is the cpuset in which your thread will be * placed. Each bit represents a CPU */ sched_setaffinity(0, sizeof(cpuset), &cpuset); while (1); ; //burns the CPU 2 return 0; } 

In a POSIX environment, you can use cpusets to control which processors or pthreads can use. This type of control is called processor affinity.

The 'sched_setaffinity' function gets the pthread identifiers and the cpuset parameter. When you use 0 in the first parameter, the calling thread will be affected

+16
Feb 19 '14 at 20:00
source share

Please find the sample program below for the cpu proximity of a specific pthread.

Add the appropriate libraries.

 double waste_time(long n) { double res = 0; long i = 0; while (i <n * 200000) { i++; res += sqrt(i); } return res; } void *thread_func(void *param) { unsigned long mask = 1; /* processor 0 */ /* bind process to processor 0 */ if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) <0) { perror("pthread_setaffinity_np"); } /* waste some time so the work is visible with "top" */ printf("result: %f\n", waste_time(2000)); mask = 2; /* process switches to processor 1 now */ if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) <0) { perror("pthread_setaffinity_np"); } /* waste some more time to see the processor switch */ printf("result: %f\n", waste_time(2000)); } int main(int argc, char *argv[]) { pthread_t my_thread; if (pthread_create(&my_thread, NULL, thread_func, NULL) != 0) { perror("pthread_create"); } pthread_exit(NULL); } 

Compile the above program with the flag -D_GNU_SOURCE.

-3
Apr 26 '12 at 22:25
source share

The scheduler will change the affinity of cpu at its discretion; to install it persistently, see cpuset on the / proc file system.

http://man7.org/linux/man-pages/man7/cpuset.7.html

Or you can write a short program that periodically sets the cpu binding (every few seconds) using sched_setaffinity

-3
Jul 30 '14 at 8:49
source share



All Articles