2013-04-30 17 views
31

Il motivo principale dell'utilizzo di atomici su mutex è che i mutex sono costosi ma con il modello di memoria predefinito per atomics è memory_order_seq_cst, non è altrettanto costoso?La sincronizzazione con `std :: mutex` è più lenta rispetto a` std :: atomic (memory_order_seq_cst) `?

Domanda: Un programma simultaneo che utilizza i blocchi può essere veloce quanto un programma senza blocco simultaneo?

In tal caso, potrebbe non valerne la pena, a meno che non voglia utilizzare memory_order_acq_rel per gli atomici.


Edit: io possa mancare qualcosa, ma non posso blocco a base di essere più veloce di libero lock-perché ogni blocco dovrà essere una barriera di memoria piena troppo. Ma con lock-free, è possibile utilizzare tecniche che sono meno restrittive rispetto alle barriere della memoria.

Quindi, tornando alla mia domanda, è il blocco più veloce del blocco basato sul nuovo standard C++ 11 con il valore predefinito memory_model?

"lock-free> = lock-based quando misurato in prestazioni" vero? Supponiamo 2 thread hardware.


Edit 2: La mia domanda non riguarda le garanzie di progresso, e forse sto usando "lock-libero" fuori contesto.

Fondamentalmente quando si hanno 2 thread con memoria condivisa, e l'unica garanzia che è necessario è che se un thread sta scrivendo l'altro thread non può leggere o scrivere, il mio presupposto è che una semplice operazione atomica compare_and_swap sarebbe molto più veloce del blocco di un mutex.

Perché se un thread non tocca mai nemmeno la memoria condivisa, si arriverà a bloccarsi e sbloccarsi più e più volte senza motivo, ma con le operazioni atomiche si usa solo 1 ciclo CPU ogni volta.

Per quanto riguarda i commenti, uno spin-lock rispetto a un mutex-lock è molto diverso quando c'è molto poco contesa.

+0

Bene, ci sono diverse garanzie di progresso tra blocchi, codice senza blocco e codice senza attesa. –

+8

[Lettura obbligatoria] (http://www.1024cores.net/home/lock-free-algorithms). –

+1

watch: https://www.youtube.com/watch?v=DCdGlxBbKU4 – NoSenseEtAl

risposta

53

programmazione Lockfree è di circa progresso garantisce: dal più forte al più debole, quelli sono -wait libera, libera lock-, -ostruzione libera, e bloccando.

Una garanzia è costosa e ha un prezzo. Più garanzie vuoi, più paghi. Generalmente, un algoritmo di blocco o datastructure (con un mutex, per esempio) ha le maggiori libertà e quindi è potenzialmente il più veloce. Un algoritmo senza attesa all'altro estremo deve utilizzare operazioni atomiche ad ogni passaggio, che può essere molto più lento.

Ottenere un blocco è in realtà piuttosto economico, quindi non dovresti mai preoccuparti di questo senza una profonda comprensione del soggetto. Inoltre, gli algoritmi di blocco con mutex sono molto più semplici da leggere, scrivere e ragionare su. Al contrario, anche le più semplici strutture di dati senza blocco sono il risultato di una ricerca lunga e mirata, ognuna delle quali vale uno o più dottori di ricerca.

In breve, gli algoritmi lock- o wait-free scambiano la latenza peggiore per latenza media e velocità effettiva. Tutto è più lento, ma niente è mai molto lento.Questa è una caratteristica molto speciale che è utile solo in situazioni molto specifiche (come i sistemi in tempo reale).

+0

ok - ma 2 thread con dati condivisi .. non sei d'accordo che uno spin-lock è più veloce di un blocco? – jaybny

+0

ad esempio un'applicazione di trading che accetta tick da 2 scambi su 2 thread. uno spin-lock non sarebbe molto più veloce di allora mutex? – jaybny

+4

@jaybny: No, perché. E uno spinlock è anche una serratura. Non cambia le garanzie fondamentali. Per favore, dai un'occhiata all'implementazione del mutex pthread per una piacevole sorpresa. –

2

Un blocco tende a richiedere più operazioni rispetto a una semplice operazione atomica. Nei casi più semplici, memory_order_seq_cst sarà circa due volte più veloce del blocco perché il blocco tende a richiedere, almeno due operazioni atomiche nella sua implementazione (una da bloccare, una da sbloccare). In molti casi, ci vuole anche di più. Tuttavia, quando inizi a sfruttare gli ordini di memoria, può essere molto più veloce perché sei disposto ad accettare meno sincronizzazione.

Inoltre, si vedrà spesso "gli algoritmi di blocco sono sempre veloci quanto gli algoritmi senza blocco". Questo è piuttosto vero. L'idea di base è che se l'algoritmo più veloce risulta essere privo di blocco, allora l'algoritmo più veloce senza il certezza del lock-free è ANCHE lo stesso algoritmo! Tuttavia, se il più veloce algortihm richiede serrature, allora quelle esigenti garanzie lockfree devono trovare un algoritmo più lento.

In generale, in alcuni algoritmi di basso livello verranno visualizzati algoritmi senza blocco, in cui è possibile ottenere prestazioni sfruttando opcodes specializzati. In quasi tutti gli altri codici, il blocco è più che soddisfacente delle prestazioni e molto più facile da leggere.

+0

"Gli algoritmi di blocco sono sempre veloci quanto gli algoritmi senza blocco." - Non lo capisco un ciclo thread-safe con memoria condivisa sarà molto più veloce facendo un semplice confronto_exchange e un lock (mutex) unlock (mutex). soprattutto se non c'è mai contesa da un altro thread. – jaybny