2015-01-28 6 views
24

Nell'implementazione di boost di shared_ptr, utilizza relaxed memory ordering to increment its reference count. Ciò sembra sicuro poiché i decrementi usano acquisire/rilasciare per assicurarsi che eventuali decrementi precedenti siano visibili al thread prima di rilasciare la memoria. Questo metodo sembra corretto e appare in Herb Sutters talk on atomicsPerché l'implementazione di shared_ptr da parte di libC++ utilizza barriere di memoria complete anziché rilassate?

In attuazione ++ libc 's utilizza full memory barriers

template <class T> 
inline T 
increment(T& t) _NOEXCEPT 
{ 
    return __sync_add_and_fetch(&t, 1); 
} 

template <class T> 
inline T 
decrement(T& t) _NOEXCEPT 
{ 
    return __sync_add_and_fetch(&t, -1); 
} 

} // name 

C'è una ragione per questa decisione? Ci sono differenze di prestazioni o di sicurezza tra di loro?

+1

In base a [dettagli dell'implementazione qui] (http://en.cppreference.com/w/cpp/memory/shared_ptr), si dice "Per soddisfare i requisiti di sicurezza dei thread, i contatori di riferimento sono in genere incrementati e decrementati usando un equivalente di std :: atomic :: fetch_add con std :: memory_order_relaxed. " Speravo di trovare la fonte per confermare la dichiarazione, ma ho difficoltà a trovare la documentazione online del codice sorgente di libC++ per gcc (anche se sono solo ricerche ingenue di Google, forse qualcuno può fornire un link). Tuttavia, noto che il tuo collegamento è per LLVM. – Suedocode

+1

Chi ha scritto quel codice, quando, perché e cos'altro hanno scritto ... se solo ci fosse un modo per scoprirlo. ;) –

+0

@Aggieboy Penso che il mirror che ho linkato sia la fonte di libC++ su GCC, basta compilarlo con '-gcc-toolchain'. libstd ++ (libreria standard predefinita su GCC) usa '__gnu_cxx :: __ exchange_and_add', che credo sia anche una barriera completa, ma non ne sono sicuro. Sembra che sia comune conoscenza che dovrebbe essere implementato con barriere rilassate ma non riesco a trovare alcuna libreria oltre a boost che lo fa –

risposta

25

Perché quando ho scritto quel codice, il compilatore (clang) non aveva ancora implementato gli atomici C++ 11. E non ci sono mai riuscito a ripulirlo.

Niente di sottile qui. :-)

+15

Infine, una risposta relativa all'atomica che ho capito! –

+0

Hah, ho appena ricevuto un "Non sei passato" quando questa risposta è stata mostrata per "controllare" le mie recensioni ... l'avevo contrassegnato come spam, pensando che qualcuno senza un rappresentante (non stava mostrando l'utente _real_ Era estremamente improbabile che avessi un codice scritto, per non parlare di un'intera libreria, che qualcun altro ora stava chiedendo: -D –

+0

A prima vista, pensavo che questa fosse una brutta auto-risposta (la faccina in particolare). Ero in guardia per gli audit, quindi sono passato, ma non è una grande scelta di auditing. –

Problemi correlati