multithreading 如何设置特定 pthread 的 CPU 亲和性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1407786/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to set CPU affinity of a particular pthread?
提问by Eduardo Bezerra
I'd like to specify the cpu-affinity of a particular pthread. All the references I've found so far deal with setting the cpu-affinity of a process (pid_t) not a thread (pthread_t). I tried some experiments passing pthread_t's around and as expected they fail. Am I trying to do something impossible? If not, can you send a pointer please? Thanks a million.
我想指定特定 pthread 的 cpu-affinity。到目前为止,我发现的所有参考资料都涉及设置进程 (pid_t) 而非线程 (pthread_t) 的 CPU 亲和性。我尝试了一些传递 pthread_t 的实验,但正如预期的那样失败了。我是在尝试做一些不可能的事情吗?如果没有,可以请你发个指针吗?太感谢了。
回答by Eduardo Bezerra
This is a wrapper I've made to make my life easier. Its effect is that the calling thread gets "stuck" to the core with id core_id
:
这是我为了让我的生活更轻松而制作的包装纸。它的作用是调用线程“卡住”到带有 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);
}
回答by nos
Assuming linux:
假设Linux:
The interface to setting the affinity is - as you've probably already discovered:
设置亲和力的界面是 - 正如您可能已经发现的那样:
int sched_setaffinity(pid_t pid,size_t cpusetsize,cpu_set_t *mask);
Passing 0 as the pid, and it'll apply to the current thread only, or have other threads report their kernel pid with the linux-specific call pid_t gettid(void);
and pass that in as the pid.
将 0 作为 pid 传递,它将仅适用于当前线程,或者让其他线程使用特定于 linux 的调用报告其内核 pidpid_t gettid(void);
并将其作为 pid 传递。
Quoting the man page
引用手册页
The affinity mask is actually a per-thread attribute that can be adjusted independently for each of the threads in a thread group. The value returned from a call to gettid(2) can be passed in the argument pid. Specifying pid as 0 will set the attribute for the calling thread, and passing the value returned from a call to getpid(2) will set the attribute for the main thread of the thread group. (If you are using the POSIX threads API, then use pthread_setaffinity_np (3) instead of sched_setaffinity().)
亲和掩码实际上是每个线程的属性,可以为线程组中的每个线程独立调整。从调用 gettid(2) 返回的值可以在参数 pid 中传递。将 pid 指定为 0 将为调用线程设置属性,并将调用返回的值传递给 getpid(2) 将为线程组的主线程设置属性。(如果您使用 POSIX 线程 API,则使用 pthread_setaffinity_np (3) 而不是 sched_setaffinity()。)
回答by ismaia
//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 POSIX environment you can use cpusets to control which CPUs can be used by processes or pthreads. This type of control is called CPU affinity.
在 POSIX 环境中,您可以使用 cpuset 来控制进程或 pthread 可以使用哪些 CPU。这种类型的控制称为 CPU 亲和性。
The function 'sched_setaffinity' receives pthread IDs and a cpuset as parameter. When you use 0 in the first parameter, the calling thread will be affected
函数“sched_setaffinity”接收 pthread ID 和一个 cpuset 作为参数。当你在第一个参数中使用 0 时,调用线程会受到影响
回答by YugiReddy
Please find the below example program to cpu-affinity of a particular pthread.
请在下面找到特定 pthread 的 cpu-affinity 示例程序。
Please add appropriate libs.
请添加适当的库。
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 above program with -D_GNU_SOURCE flag.
使用 -D_GNU_SOURCE 标志编译上面的程序。
回答by MichaelMoser
The scheduler will change the cpu affinity as it sees fit; to set it persistently please see cpuset in /proc file system.
调度程序会在它认为合适的时候更改 CPU 关联;要永久设置它,请参阅 /proc 文件系统中的 cpuset。
http://man7.org/linux/man-pages/man7/cpuset.7.html
http://man7.org/linux/man-pages/man7/cpuset.7.html
Or you can write a short program that sets the cpu affinity periodically (every few seconds) with sched_setaffinity
或者您可以编写一个简短的程序,使用 sched_setaffinity 定期(每隔几秒)设置 cpu 关联