如何设置特定pthread的CPU亲和力?
我想指定特定pthread的cpu-affinity。 到目前为止我发现的所有引用都涉及到设置进程(pid_t)的cpu-affinity而不是线程(pthread_t)。 我尝试了一些传递pthread_t的实验,正如预期的那样,它们失败了。 我想做一些不可能的事情吗? 如果没有,你可以发一个指针吗? 太感谢了。
这是我为了让自己的生活更轻松而做的包装。 其效果是调用线程被“卡住”到ID为core_id
的核心:
// core_id = 0, 1, ... n-1, where n is the system's 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); }
假设linux:
设置亲和力的界面是 – 你可能已经发现:
int sched_setaffinity(pid_t pid,size_t cpusetsize,cpu_set_t *mask);
将0作为pid传递,它将只应用于当前线程,或者让其他线程使用linux特定的调用pid_t gettid(void)报告它们的内核pid。 并把它作为pid传入。
引用手册页
亲和性掩码实际上是每个线程属性,可以针对线程组中的每个线程独立调整。 从调用gettid(2)返回的值可以在参数pid中传递。 将pid指定为0将为调用线程设置属性,并将调用返回的值传递给getpid(2)将设置线程组的主线程的属性。 (如果使用POSIX线程API,则使用pthread_setaffinity_np(3)而不是sched_setaffinity()。)
//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; }
在POSIX环境中,您可以使用cpusets来控制哪些CPU可以被进程或pthreads使用。 这种types的控制被称为CPU亲和力。
函数“sched_setaffinity”接收pthread ID和一个cpuset作为参数。 在第一个参数中使用0时,调用线程将受到影响
请查找下面的示例程序,以获取特定pthread的cpu-affinity。
请添加适当的库。
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); }
使用-D_GNU_SOURCE标志编译上述程序。
调度程序会根据自己的情况更改cpu关联性。 要持久地设置它,请参阅/ proc文件系统中的cpuset。
http://man7.org/linux/man-pages/man7/cpuset.7.html
或者你可以写一个简短的程序,用sched_setaffinity定期(每隔几秒)设置一次cpu关联