web-dev-qa-db-ja.com

特定のpthreadのCPUアフィニティを設定する方法は?

特定のpthreadのCPUアフィニティを指定したいと思います。これまでに見つけたすべての参照は、スレッド(pthread_t)ではなく、プロセス(pid_t)のCPU親和性の設定を扱っています。 pthread_tを渡すいくつかの実験を試みましたが、予想どおり失敗しました。不可能なことをしようとしていますか?そうでない場合は、ポインタを送ってください。感謝万円。

53
Michael Wagner

これは私の人生を楽にするために作ったラッパーです。その効果は、呼び出しスレッドが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);
}
53
Eduardo Bezerra

Linuxを想定:

アフィニティを設定するためのインターフェースは、おそらく既に発見されているとおりです:

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

Pidとして0を渡すと、現在のスレッドにのみ適用されます。または、Linux固有の呼び出しpid_t gettid(void)で他のスレッドにカーネルpidを報告させます。そしてそれをpidとして渡します。

manページ の引用

アフィニティマスクは、実際にはスレッドごとの属性であり、スレッドグループ内のスレッドごとに個別に調整できます。 gettid(2)の呼び出しから返された値は、引数pidで渡すことができます。 pidを0に指定すると、呼び出しスレッドの属性が設定され、呼び出しから返された値をgetpid(2)に渡すと、スレッドグループのメインスレッドの属性が設定されます。 (POSIXスレッドAPIを使用している場合は、sched_setaffinity()の代わりにpthread_setaffinity_np(3)を使用します。)

41
nos
//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を使用すると、呼び出しスレッドが影響を受けます

19
ismaia