2012-04-07 36 views
8

Qualcuno ha esperienza con il piuttosto nuovo std::async? Attualmente stiamo implementando un parser di file parallelo, che legge un blocco di file e passa questo blocco a una funzione asincrona.Comportamento di GCC con std :: async (std :: launch :: async) rispetto al comportamento di Clang

L'utilizzo di Clang (v3.0) funziona in modo ottimale con le politiche di default std::async (dipendenti dall'implementazione). Su una macchina a due core, attiva fino a 4 thread ciò che funziona davvero bene.

Ma con GCC (v4.7), il thread di lettura del file non genera nuovi thread, rendendo il programma alla fine completamente sequenziale.

Utilizzando std::launch::async, entrambe le versioni stanno praticamente facendo lo stesso (come dovrebbe essere il caso).

Qualcuno conosce lo stato della corrente delle funzionalità di threading di C++ 11 di GCC? O potrebbe essere un errore nella nostra implementazione?

Codice breve:

while (readNewChunk()) { 
    Chunk &chunk = fileReader_.getChunk(); //reading the file 
    ChunkLoader *chunkLoader = new ChunkLoader(); 
    auto ftr = std::async(std::launch::async, &ChunkLoader::createDictionaries, chunkLoader); 
    dictCreationFutures_.push_back(std::move(ftr)); 
} 
+0

Mi piacerebbe davvero usare Boost. Non sarà un grande salto al corretto supporto per C++ 11. I nuovi modelli di threading in C++ 11 richiedono un layout di memoria diverso da quello utilizzato da GCC o MSVC e non sono implementati molto. –

risposta

15

Il comportamento è all'interno delle specifiche, anche se non è quello che desideri. Se non si specifica un criterio di avvio, è considerato come async|deferred, il che significa che è responsabilità dell'implementazione decidere quale. GCC capita di scegliere sempre deferred se viene data una scelta.

+0

Grazie per averlo chiarito. Pensavo che tutte le implementazioni attuali fossero un po '"più intelligenti" e non solo facendo un semplice _deferred_. – Bouncner

+4

Mi permetto di non essere d'accordo. Questo è ciò che dice lo standard (enfasi sulla mia): "Se questa politica viene specificata insieme ad altre politiche, come quando si utilizza un valore di politica di' launch :: async | launch :: deferred', le implementazioni devono rinviare l'invocazione o la selezione di la politica _quando non è più possibile sfruttare in modo efficace la concorrenza. " Questo è molto diverso dal lancio di qualsiasi nuovo thread differito. –

5

EDIT2: Mi spiego un po 'di più.

std :: async promette un "futuro"; cioè: quando lo vuoi, sarà lì. Può essere calcolato ora, può essere calcolato quando lo chiedi, stiamo solo promettendo che accadrà.

Come il poster sotto di me fa notare, GCC è impostato su "differito" (il che significa che adempie a tale promessa quando viene richiesto, e probabilmente non in anticipo). Il motivo di questo default è dato dal fatto che GCC non fornisce ancora il supporto per il threading C++ 11 corretto. Non ha un buon programmatore di thread interno, tra molte altre cose. È un po 'un trucco. No, più come un mucchio di hack. Infatti, se si scrive codice threadato in C++ 11 su GCC, è più importante che quando implementano le funzionalità, funzionerà correttamente; Al momento, funziona principalmente. Voglio dire, ottieni il risultato alla fine, giusto?

Se si dice di lanciare un thread, lo sarà, perché è troppo stupido (al momento) per rendersi conto che può e deve da solo (a differenza di CLang, che al momento dispone di un programma di thread interno migliore).

EDIT: Seriamente? Down-modding errato!

Ecco il mio riferimento! http://gcc.gnu.org/projects/cxx0x.html. Nota che quasi tutto sotto 'concorrenza' incluso 'modello di memoria' è indicato come NO. GCC.GNU.org. Sono l'autorità su GCC che conosci.

leggermente modificati dal mio commento:

Vorrei davvero consiglia di utilizzare Boost. Non sarà un grande salto al corretto supporto per C++ 11 quando GCC è pronto. I nuovi modelli di threading in C++ 11 richiedono un layout di memoria diverso da quello utilizzato da GCC o MSVC e non sono ancora implementati molto.

+3

Cosa è cambiato in C++ 11 in termini di "layout di memoria"? –

+0

@NicolBolas http://gcc.gnu.org/projects/cxx0x.html. Nota: quasi tutto sotto 'concorrenza' incluso 'modello di memoria' è indicato come NO –

+5

Sì, ma ciò non spiega cosa è cambiato con "memoria * layout *". Layout è su dove le cose vanno in relazione ad altre cose. Il modello di memoria * * spiega le regole su quando le variabili accessibili diventano visibili in altri thread e così via. –

1

Quindi ho capito che sono passati 2 anni, ma non posso fare a meno di sentire la necessità di rispondere al commento di @ std''OrgnlDave su GCC vs. CLang, per notare che almeno al momento, gennaio 2015, entrambi clang versione 3.5 e GCC versione 4.9 hanno esattamente lo stesso comportamento.Questo comportamento è, quando non viene fornito alcun criterio di lancio, di default diverso ed eseguito quando future :: get viene chiamato, e solo quando il criterio di avvio asincrono viene esplicitamente fornito, il compilatore porterà all'esecuzione della funzione in background.

Problemi correlati