2013-04-16 13 views
7

Próbuję ustawić główne powinowactwo (wątek # 1 przechodzi na pierwszy rdzeń, wątek # 2 przechodzi na drugi rdzeń, ...) podczas używania std :: thread w C++ 11Zdobywanie powinowactwa rdzeni w C++ 11 przez pthreads

Szukałem już różnych tematów i w Internecie i wydaje się, że API C++ 11 nie zapewnia tak niskiego poziomu funkcji.

Z drugiej strony, pthreads pochodzą z pthread_setaffinity_np który byłby użyteczny, czy mogę dostać „pthread_t” wartość mojego std :: gwint (nie wiem, czy to jest człowiek rozsądny lub przynajmniej uzasadniony sprzedaży dla tego).

Przykładowy program, co bym chciał mieć w końcu jest to:

#include <thread> 
#include <pthread.h> 
#include <iostream> 
#include <stdio.h> 
#include <stdlib.h> 

#define CORE_NO 8 

using namespace std; 

void run(int id) { 
    cout << "Hi! I'm thread " << id << endl; 
    // thread function goes here 
} 

int main() { 
    cpu_set_t cpu_set; 

    CPU_ZERO(&cpu_set); 
    for(int i=0; i<CORE_NO; i++) 
     CPU_SET(i, &cpu_set); 

    thread t1(run, 1); 

    // obtaining pthread_t from t1 

    /* 
    pthread_t this_tid = foo(t1); 
    pthread_setaffinity_np(this_tid, sizeof(cpu_set_t), &cpu_set); 
    */ 

    t1.join(); 

    return 0; 
} 

bym naprawdę nie chce zmienić całą architekturę mojego projektu (który musi zapewnić takie charakterystyczne). Mam teraz masywne użycie std :: thread, ale mogę również używać API pthread, jak widzieliśmy w przykładzie.

Czy istnieje sposób, aby rozwiązać ten problem?

+0

"która musi zapewniać taką właściwość" - jaką poprawę wydajności zaobserwowałeś po ustawieniu powinowactwa nici? Czy masz jakieś liczby? –

+0

@Martin James - oddelegowany. Rob013 - Z mojego doświadczenia wynika, że ​​musisz mieć bardzo konkretny zestaw okoliczności, zanim zaczniesz się bawić z kluczowymi uderzeniami, co system automatycznie zrobi. I wtedy musisz mieć ładunek kodu do opracowania w środowisku wykonawczym optymalnego powinowactwa do wątków na dowolnym sprzęcie, na którym program jest uruchamiany, a to jest mnóstwo kłopotów. Prawdopodobnie lepiej będzie, jeśli OS zacznie działać najlepiej. Jeśli naprawdę potrzebujesz pokrewieństwa rdzenia, prawdopodobnie będziesz potrzebował także pokrewieństwa pamięci, aby uzyskać jakąkolwiek korzyść, a to i tak doprowadzi twoją architekturę do końca. – bazza

+2

Dzięki za porady. Rozumiem twój punkt widzenia, jestem pewien, że zarządzanie wątkami systemu operacyjnego byłoby lepsze niż student, który dowiedział się, co to jest koligacja zaledwie kilka dni temu. Nawiasem mówiąc, moje pytanie dotyczyło konkretnego problemu wewnątrz projektu portowania, więc powiedziano mi tylko "* my * używamy zasadniczego powinowactwa. I dla moich celów rozwiązanie Joachima jest wystarczające. – Rob013

Odpowiedz

10

Możesz uzyskać macierzystą obsługę wątku za pomocą funkcji native_handle.

Przykład w odsyłaczu odnośnikowym używa go nawet do wywoływania funkcji pthread.

+1

Tak, ale z tego co wiem, nie można zagwarantować, że będzie to typ pthread_t. Sfery PThreads są często warstwą na wierzchu rodzimych wątków systemu operacyjnego. Linux z NPTL jest prawdopodobnie wyjątkiem. Będziesz więc potrzebować procedur specyficznych dla systemu operacyjnego, aby poradzić sobie z podstawowym powinowactwem. – bazza

7

Nie wiem, czy jest to odpowiednie podejście w twoim przypadku, ale zwykle robię to, aby wywołać prymitywy powinowactwa z wątku. Na przykład umieścić fragment kodu podobnego do tego gdzieś na początku funkcji gwintowaną:

const int err = pthread_setaffinity_np(pthread_self(),...); 

Wezwanie do pthread_self() zwróci identyfikator wątku wywołującego.