Привязка Pthread перед созданием потоков

Мне нужно установить привязку (поток к ядру, например: 1-й поток к 1-му ядру) перед созданием потока. Что-то вроде KMP_AFFINITY в OpenMP. Является ли это возможным?

изменить: я пытаюсь таким образом, но не работает:/

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

person JudgeDeath    schedule 24.08.2014    source источник
comment
Вы устанавливаете привязку так, чтобы она запускала все потоки во всех потоках HW. Вы должны установить сходство отдельно для каждого потока, т.е. переместить настройку сходства в цикл создания потока.   -  person JarkkoL    schedule 24.08.2014
comment
Ok. Я попробую. Можно ли установить сходство после запуска программы для всех созданных потоков? Например, когда я использую таблицу потоков несколько раз.   -  person JudgeDeath    schedule 25.08.2014
comment
Вы можете установить сходство для созданного потока с помощью pthread_setaffinity_np   -  person JarkkoL    schedule 25.08.2014


Ответы (3)


Как упоминалось ранее, вы должны использовать pthread_attr_setaffinity_np для привязки потока к определенному ядру. Количество ядер ЦП, доступных в вашей системе, можно получить (см. код ниже).

При создании потоков с pthread_create каждый раз вам нужно передавать экземпляр pthread_attr_t, который устанавливается с соответствующим cpu_set_t. Каждый раз перед добавлением следующего идентификатора ядра процессора в набор приходится либо очищать cpu_set_t, либо удалять введенное ранее число (я выбрал первый вариант). Вам нужно иметь ровно один ЦП в наборе при создании потока, если вы хотите точно определить, на каком ЦП будет выполняться поток (см. код ниже).

#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;
}
person grelt    schedule 25.08.2014

Вы можете вызвать pthread_self(), чтобы получить идентификатор основного потока и использовать его в pthread_setaffinity_np.

person Pauli Nieminen    schedule 24.08.2014

Вы можете использовать pthread_attr_setaffinity_np для установки атрибутов сходства для функции pthread_create.

person JarkkoL    schedule 24.08.2014