5

I need to set the affinity (thread to core, eg: 1st thread to 1st core) before creating a thread. Something like KMP_AFFINITY in OpenMP. Is it possible?

edit: I try in this way, but dont' work :/

void* DoWork(void* args)
{
    int nr = (int)args;
    printf("Wątek: %d, ID: %d, CPU: %d\n", nr,pthread_self(), sched_getcpu());  
}


int main()
{   
    int count = 8;
    pthread_t threads[count];

    pthread_attr_t attr;
    cpu_set_t mask;
    CPU_ZERO(&mask);
    pthread_attr_init(&attr);

    for (int i = 0; i < count ; i++)
         CPU_SET(i, &mask);

    pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &mask);

    for(int i=0; i<count ; i++)
    {

        pthread_create(&threads[i], &attr, DoWork, (void*)i);
    }

    for(int i=0; i<count ; i++)
    {
        pthread_join(threads[i], NULL);
    }
}
JudgeDeath
  • 151
  • 1
  • 2
  • 9
  • You set the affinity so that it runs all the threads in all HW threads. You have to set the affinity separately for each thread, i.e. move the affinity setup within your thread creation loop. – JarkkoL Aug 24 '14 at 16:53
  • Ok. I try It. It is posible to set affinity after running program for all created thread? For example, when I use thread table several times. – JudgeDeath Aug 24 '14 at 21:31
  • You can set the affinity for created thread with pthread_setaffinity_np – JarkkoL Aug 25 '14 at 00:54

3 Answers3

28

As mentioned before you should use pthread_attr_setaffinity_np to bind a thread to a specific core. The number of CPU cores available in your system can be retrieved (see code below).

While creating the threads with pthread_create, each time you have to pass an instance of pthread_attr_t which is set with appropriate cpu_set_t. Every time you have to either clear the cpu_set_t or remove the previously entered number (I chose the former option) before adding the next identifier of CPU core to the set. You need to have exactly one CPU in the set when creating the thread if you want to determine exactly on which CPU the thread will be executed (see code below).

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

void* DoWork(void* args) {
    printf("ID: %lu, CPU: %d\n", pthread_self(), sched_getcpu());
    return 0;
}

int main() {   

    int numberOfProcessors = sysconf(_SC_NPROCESSORS_ONLN);
    printf("Number of processors: %d\n", numberOfProcessors);

    pthread_t threads[numberOfProcessors];

    pthread_attr_t attr;
    cpu_set_t cpus;
    pthread_attr_init(&attr);

    for (int i = 0; i < numberOfProcessors; i++) {
       CPU_ZERO(&cpus);
       CPU_SET(i, &cpus);
       pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &cpus);
       pthread_create(&threads[i], &attr, DoWork, NULL);
    }

    for (int i = 0; i < numberOfProcessors; i++) {
        pthread_join(threads[i], NULL);
    }

    return 0;
}
grelt
  • 396
  • 2
  • 5
1

You can call pthread_self() to get thread id for your main thread and use that in pthread_setaffinity_np.

Pauli Nieminen
  • 1,100
  • 8
  • 7
1

You can use pthread_attr_setaffinity_np for setting affinity attributes for pthread_create function.

JarkkoL
  • 1,898
  • 11
  • 17