66

我想指定特定 pthread 的 cpu 亲和性。到目前为止,我发现的所有参考资料都涉及设置进程 (pid_t) 而不是线程 (pthread_t) 的 cpu 亲和性。我尝试了一些通过 pthread_t 的实验,但正如预期的那样,它们失败了。我在尝试做一些不可能的事情吗?如果没有,您可以发送一个指针吗?太感谢了。

4

5 回答 5

69

这是我为让我的生活更轻松而制作的包装。它的效果是调用线程“卡”在 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);
}
于 2012-07-20T16:38:19.623 回答
51

假设Linux:

设置亲和力的界面是 - 正如您可能已经发现的那样:

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

将 0 作为 pid 传递,它将仅应用于当前线程,或者让其他线程通过特定于 linux 的调用报告其内核 pid 并将pid_t gettid(void);其作为 pid 传递。

引用手册页

亲和掩码实际上是每个线程的属性,可以为线程组中的每个线程独立调整。调用 gettid(2) 返回的值可以在参数 pid 中传递。将 pid 指定为 0 将为调用线程设置属性,并将调用返回的值传递给 getpid(2) 将为线程组的主线程设置属性。(如果您使用的是 POSIX 线程 API,则使用 pthread_setaffinity_np (3) 而不是 sched_setaffinity()。)

于 2009-09-10T21:34:18.120 回答
27
//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 来控制进程或 pthread 可以使用哪些 CPU。这种类型的控制称为 CPU 亲和性。

函数 'sched_setaffinity' 接收 pthread ID 和一个 cpuset 作为参数。当你在第一个参数中使用 0 时,调用线程会受到影响

于 2014-02-19T20:00:33.437 回答
-4

请在下面的示例程序中找到特定 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 标志编译上述程序。

于 2012-04-26T22:25:42.657 回答
-6

调度程序将根据需要更改 cpu 亲和性;要永久设置它,请参阅 /proc 文件系统中的 cpuset。

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

或者您可以编写一个简短的程序,使用 sched_setaffinity 定期(每隔几秒)设置 cpu 亲和性

于 2014-07-30T08:49:36.703 回答