web-dev-qa-db-fra.com

comment définir l'affinité CPU d'un pthread particulier?

Je voudrais spécifier l'affinité cpu d'un pthread particulier. Toutes les références que j'ai trouvées jusqu'à présent concernent la définition de l'affinité cpu d'un processus (pid_t) et non d'un thread (pthread_t). J'ai essayé quelques expériences en passant autour de pthread_t et comme prévu, elles échouent. Suis-je en train de faire quelque chose d'impossible? Sinon, pouvez-vous envoyer un pointeur s'il vous plaît? Merci mille fois.

53
Michael Wagner

C'est un emballage que j'ai fait pour me faciliter la vie. Son effet est que le thread appelant est "bloqué" sur le noyau avec 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

En supposant que Linux:

L'interface pour définir l'affinité est - comme vous l'avez probablement déjà découvert:

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

Passer 0 comme pid, et cela s'appliquera uniquement au thread actuel, ou demander à un autre thread de rapporter son pid de noyau avec l'appel spécifique à Linux pid_t gettid (void); et passez-le comme pid.

Citant le page de manuel

Le masque d'affinité est en fait un attribut par thread qui peut être ajusté indépendamment pour chacun des threads d'un groupe de threads. La valeur renvoyée par un appel à gettid (2) peut être passée dans l'argument pid. La spécification de pid à 0 définira l'attribut du thread appelant et la transmission de la valeur renvoyée par un appel à getpid (2) définira l'attribut du thread principal du groupe de threads. (Si vous utilisez l'API des threads POSIX, utilisez alors pthread_setaffinity_np (3) au lieu de sched_setaffinity ().)

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;
}

Dans l'environnement POSIX, vous pouvez utiliser des cpusets pour contrôler quels processeurs peuvent être utilisés par les processus ou les pthreads. Ce type de contrôle est appelé affinité CPU.

La fonction 'sched_setaffinity' reçoit des identifiants pthread et un cpuset comme paramètre. Lorsque vous utilisez 0 dans le premier paramètre, le thread appelant sera affecté

19
ismaia