2013-04-16 17 views
7

Sto cercando di impostare affinità nucleo (il thread # 1 va sul primo core, il thread # 2 sul secondo core, ...) durante l'utilizzo di std :: thread in C++ 11Ottenere thread affinità core in C++ 11 attraverso pthreads

Ho già cercato su vari argomenti e su Internet e sembra che l'API C++ 11 non fornisca funzionalità di livello così basso.

D'altra parte, pthreads sono dotati pthread_setaffinity_np che sarebbe utile se potessi ottenere il valore "pthread_t" del mio std :: filo (non so se questo è umano ragionevole o almeno legittimo chiedere per questo).

Un programma di esempio di quello che avrei voluto avere alla fine è questo:

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

Mi piacerebbe molto preferiscono non cambiare tutta l'architettura del mio progetto (che deve fornire tale caratteristica). Ora ho un uso massiccio di std :: thread, ma posso anche usare l'API pthread in aggiunta, come hai visto nell'esempio.

C'è un modo per risolvere questo problema?

+0

'che deve fornire tale caratteristica' - quale miglioramento delle prestazioni avete visto dopo aver impostato l'affinità del filo? Hai qualche numero? –

+0

@Martin James - distaccato. Rob013 - Nella mia esperienza devi avere una serie di circostanze molto particolare prima di andare in giro con i battiti di affinità core che il sistema operativo farà comunque automaticamente. E poi devi avere un carico di codice per elaborare a runtime l'affinità ottimale per i thread su qualsiasi hardware su cui viene eseguito il programma, e questo è un carico di seccature. Probabilmente stai meglio lasciare che il sistema operativo faccia del suo meglio per cominciare. Se hai davvero bisogno di affinità di base, probabilmente avrai bisogno anche dell'affinità della memoria per trarne vantaggio, e ciò rovinerà completamente la tua architettura. – bazza

+2

Grazie per il vostro consiglio. Vedo il tuo punto di vista, sono abbastanza sicuro che la gestione dei thread OS sarebbe meglio di uno studente che ha imparato quale affinità di base è solo un paio di giorni fa. A proposito, la mia domanda riguardava un problema specifico all'interno di un progetto di porting, quindi mi è stato detto solo "* usiamo l'affinità di base. E per i miei obiettivi la soluzione di Joachim è abbastanza. – Rob013

risposta

10

È possibile ottenere l'handle nativo per il thread con la funzione native_handle.

L'esempio nel riferimento collegato utilizza anche questo per chiamare le funzioni pthread.

+1

Sì, ma per quanto posso dire che non è garantito che sia di tipo pthread_t. Gli stessi PThread sono spesso un livello in cima ai thread nativi del sistema operativo sottostante. Linux con NPTL è probabilmente l'eccezione. Quindi avrai bisogno di routine specifiche del sistema operativo per gestire l'affinità principale. – bazza

7

Non so se è un approccio adatto nel tuo caso, ma quello che faccio di solito è chiamare le primitive di affinità all'interno del thread. Per esempio, ho posto un frammento di codice simile a questa da qualche parte all'inizio della funzione filettato:

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

La chiamata a pthread_self() restituirà l'ID del thread chiamante.