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

j'aimerais préciser l'affinité cpu d'un pthread particulier. Toutes les références que j'ai trouvées jusqu'à présent traitent de la définition de l'affinité cpu d'un processus (pid_t) et non d'un thread (pthread_t). J'ai tenté quelques expériences en passant pthread_t autour et comme prévu, ils échouent. Suis-je en train d'essayer de faire quelque chose d'impossible? Si non, pouvez-vous envoyer un pointeur s'il vous plaît? Merci un million.

52
demandé sur Eduardo Bezerra 2009-09-11 01:19:18

5 réponses

c'est un papier que j'ai fait pour me faciliter la vie. Son effet est que le fil appelant est "collé" au cœur avec l'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);
}
46
répondu Eduardo Bezerra 2014-02-19 15:10:56

supposant 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);

passant le 0 comme pid, et il s'appliquera uniquement au thread courant, ou aura un autre thread report leur noyau pid avec l'appel spécifique linux pid_t gettid(void); et passer que dans le pid.

citant la man page

le masque d'affinité est fait par thread attribut qui peut être réglé indépendamment pour chacun des threads dans un groupe de threads. Valeur retourné à partir d'un appel à gettid(2) peut être passé en argument pid. Spécifier le pid comme 0 définira le attribut pour le fil appelant, et transmettre la valeur retournée par un appel pour getpid(2) définit l'attribut pour le fil principal du fil groupe. (Si vous utilisez le POSIX API threads, puis utiliser pthread_setaffinity_np (3) plutôt sched_setaffinity ().)

37
répondu nos 2009-09-10 21:34:18
//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 cpusets pour contrôler quels CPU peuvent être utilisés par des processus ou des pthreads. Ce type de contrôle est appelé affinité CPU.

la fonction "sched_setaffinity" reçoit les ID pthread et un cpuset comme paramètre. Lorsque vous utilisez 0 dans le premier paramètre, le thread appelant sera affecté

16
répondu ismaia 2014-02-19 20:00:33

Veuillez trouver ci-dessous l'exemple du programme de l'uc de l'affinité d'un pthread.

veuillez ajouter les titres appropriés.

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

compiler le programme ci-dessus avec le drapeau-D_GNU_SOURCE.

-3
répondu YugiReddy 2012-04-27 01:41:14

Le planificateur va changer l'affinité cpu comme il l'entend; pour régler définitivement veuillez voir cpuset dans le système de fichiers /proc.

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

Ou vous pouvez écrire un programme court qui définit l'affinité cpu périodiquement (toutes les quelques secondes) avec sched_setaffinity

-3
répondu MichaelMoser 2014-07-30 08:49:36