2016-02-08 5 views
8

Sono Computing float s molteplici fili e memorizzare i risultati in intervalli non sovrapposti dello stesso vector<float> come segue:Sta chiamando safe std :: copy da più thread per diversi intervalli dello stesso vettore?

Prima di eseguire qualsiasi fili I preassegnati utilizzando vector::reserve.

In ogni filetto una vector di risultati specifici filo viene calcolato e poi copiato nel contenitore bersaglio simili:

vector<float>::iterator destination = globalVector.begin() + threadSpecificIndex; 
std::copy(localVector.begin(), localVector.end(), destination); 

È una pratica sicura?

+8

'std :: vector :: reserve' non funzionerà, è necessario in realtà' ridimensionare() '- altrimenti si scriverà oltre l'effettivo' end() 'del vettore. – mindriot

+0

Per aggiungere al commento @mindriot: Se il tipo che stai memorizzando non ha un costruttore predefinito puoi usare qualcosa come "boost :: optional' invece del tuo tipo direttamente. Ciò avrebbe aggiunto il vantaggio che si può dire se qualcosa è fallito senza dover creare uno di quegli oggetti "non ancora reali" che non si costruiscono completamente da soli. Quelli sono abomini. –

risposta

7

Il primo vector::reserve non crea alcun elemento. Imposta solo la capacità del vettore. Se hai bisogno degli elementi per esserci, hai bisogno di vector::resize o semplicemente di costruire il vettore con le dimensioni necessarie.

In secondo luogo, la regola generale è se si dispone di un oggetto condiviso tra thread e almeno uno di essi è un writer che è necessario sincronizzare. Poiché in questo caso "l'oggetto" è l'intervallo di iteratore e non si sovrappongono, va bene a questo proposito. Finché la dimensione dei vettori non viene cambiata, dovresti stare bene.

Un problema che potresti avere è la condivisione errata. Se la stessa riga della cache contiene variabili utilizzate da thread differenti, queste devono essere risincronizzate ogni volta che viene aggiornata una variabile nella riga. Questo può rallentare un po 'le prestazioni del codice.

+0

Buon punto sulla cache. Mi chiedo se qualsiasi altro contenitore si adatterebbe meglio qui, ma credo che anche con questa cosa della cache, il vettore sia il più veloce. –

+0

Il vettore @piotrsmaron è normalmente l'opzione migliore. Finché l'intervallo di iteratori è maggiore di una linea della cache, la condivisione falsa non dovrebbe essere un problema. L'ho appena menzionato come una potenziale trappola e l'ho visto su piccole distanze. – NathanOliver

+0

@jaggedSpire Nessun problema. Grazie per la revisione della grammatica. – NathanOliver

2

Se il vettore è fissato dimensioni (e sembra che esso ha dalla sua domanda), e gli intervalli non sono sovrapposte, quindi:

  1. vettore non sarà riassegnato
  2. diversi fili no accedere alla stessa memoria

quindi non vedo alcuna corsa di dati qui. (Ma secondo il primo commento alla tua domanda, devi assicurarti che quel vettore ha questa dimensione fissa quando viene usato). Puoi anche vedere la sezione "Razze dati" per std :: copy: http://www.cplusplus.com/reference/algorithm/copy/

+0

A meno che non sia 'vector ' –

+0

Sì, è corretto. Per vettore intendevo il vettore , di cui si chiedeva l'autore della domanda, ma grazie per averlo chiarito. –