2016-01-10 28 views
7

Sto installando nel framework uno strumento che genererà una tabella di dati binari. Ho un piano per rendere questo multithreaded per sfruttare appieno i 24 core a mia disposizione. (Sto stimando che il tempo sul muro per la generazione dei dati sarà di circa 50 giorni, in un singolo thread). L'ho fatto in passato usando il design server/client con la comunicazione socket in quanto avevo bisogno di distribuirlo su più macchine.È necessario il mutex per offset diversi nella memoria heap allocata

Questa volta, sto guardando un singolo approccio macchina/multi-thread e sto cercando di capire come farlo nel modo giusto.

Il thread principale gestirà l'assegnazione delle attività a ogni thread secondario e determinerà l'offset nella memoria allocata.

Ogni thread scrive in un intervallo di indirizzi univoco all'interno della memoria allocata. Poiché questi blocchi non si sovrappongono mai tra i record, non ci saranno mai due tentativi di scrivere lo stesso offset.

 {Meta Data}{Rec1}{Rec2}{Rec3}{Rec4}{...}{...}{...}

void computeRecord(void *taskInput) 
{ 
    struct TaskData *taskData = (TaskData *)(taskInput); 

    RecordData data; 
    // A huge long computation block to populate data 
    // (4-5 second run time) 

    long record_id = taskData->record_id; 
    char *buffer = taskData->start_buffer; 

    // mutex lock needed here ?? 

    int n_bytes = sizeof(RecordData) 
    memcpy((char *)(buffer+record_id*n_bytes), (char *)(&recordData) n_bytes); 

    // mutex unlock here ? 
} 

configurazione Long. Breve domanda Il mutex è necessario in questo caso?

+1

Non penso sia necessario, ma potrebbe essere alcune sottigliezze quindi non risponderò. –

+3

Non vorrei che un compito di 50 giorni di calcolo vivesse interamente nella memoria. Quel livello di calcolo: i bit generati dovrebbero essere facili da salvare su disco senza danneggiare la larghezza di banda, il che consente di raccogliere facilmente esecuzioni parziali e separare il consumo dalla produzione. Per la tua domanda, tuttavia, non dovrebbe essere necessario alcun mutex se i tuoi offset sono ragionevolmente allineati sulla maggior parte delle architetture. – Yakk

+0

Hai pensato di usare OpenMP: è esatto il tipo di parallelismo che è stato progettato per indirizzare lo – Christophe

risposta

5

Per prestazioni ottimali, è necessario allineare i dati alle linee della cache: ciò eviterà che i diversi core della CPU "rimbalzino" tra le linee della cache.

Ma a prescindere da ciò, purché stiamo parlando di byte separati che sono interagiti in modo indipendente, non è necessaria alcuna protezione. Solo se più di un thread accede allo stesso byte [si applica anche quando si accede a più byte, ovviamente].

Modifica: questa istruzione è ovviamente vera solo se il processore ha l'indirizzamento di byte. Il processore che viene in mente che non è Alpha, ma potrebbero essercene altri. (Modifica2: No, non importa nel compilatore compatibile con C++ 11, è compito del compilatore occuparsi dell'indirizzamento dei byte in modo thread-safe)

+0

Sfortunatamente, non ho il controllo sulla struttura della tabella di dati (o dei record in essa contenuti. Sto generando dati per un'applicazione che definisce l'interfaccia nei dati. – MikeMayer67

+0

Stai affermando che non ci sono processori in cui la lettura/scrittura della memoria è più grande di un byte alla volta? – Yakk

+0

@Yakk: corretto e ho aggiunto una dichiarazione in tal senso. –