2013-11-03 23 views
8

può puntare a chiunque di risultati dei benchmark che confrontano le prestazioni della C11/codice C++ 11 utilizzando le operazioni atomiche rilassato (in particolare memory_order_release e memory_order_acquire, ma anche memory_order_consume e memory_order_relaxed) contro il default memory_order_seq_cst? Tutte le architetture sono di interesse. Grazie in anticipo.C11/C++ 11 di memoria debole benchmark

+7

Immagino che le prestazioni non contano tanto quanto la correttezza. Dovresti usare l'ordine di memoria per la semantica dei tuoi carichi e dei depositi corretto, non usare qualcosa di diverso perché è forse 3 cicli più veloce. OTOH, se non hai idea, rimani con l'impostazione predefinita, che _may_ è leggermente più lenta (spesso non è pari), ma è _garanziata_ per essere corretta. Non c'è niente di più di un incubo del codice multithread "ottimizzato" che non è corretto. – Damon

+2

L'ordine di memoria sequenzialmente coerente coerente è più rigido di qualsiasi altro, quindi le prestazioni sono l'unico motivo per utilizzare ordini più deboli. So come ragionare sulla correttezza in entrambi i casi, ma il ragionamento è più difficile per gli ordini più deboli. In ogni caso, non si tratta di 3 cicli; anche su un i7, lo svuotamento del buffer del negozio è tipicamente di decine di cicli (forse molto di più sui processori precedenti), e la differenza tra seq_cst e consumare su ARM è ancora maggiore. – user2949652

+0

È difficile ottenere risultati significativi da un benchmark. Un singolo carico/negozio è difficilmente misurabile in modo affidabile. Caricare e memorizzare lo stesso valore (o un insieme di valori) molte volte senza sincronizzazione eseguirà solo il benchmark del thrash della cache, ma non l'operazione effettiva. La sincronizzazione misurerà la primitiva di sincronizzazione, che è ~ 1000 volte più costosa. Quello, e davvero non hai altra scelta che scrivere un codice corretto. Se ti capita qualcosa, prima della garanzia su alcuni dati, non puoi lasciarlo solo perché sarebbe più veloce. – Damon

risposta

0

Questa potrebbe non essere la soluzione migliore, ma finora ho utilizzato CDSChecker per alcuni benchmark in uno dei miei progetti. Non l'ho ancora usato su programmi completi ma più solo su unità indipendenti.

+0

CDSChecker non è progettato per il benchmarking, solo per test esaustivi di correttezza. CDSChecker non fornisce informazioni su quali saranno le prestazioni del tuo codice. – briand

1

Ho fatto un po 'di benchmark su ARMv7, vedere https://github.com/reinhrst/ARMBarriers per il report, le diapositive per il mio talk a EuroLLVM e il codice seqlock che ho usato.

Breve storia: nel codice seqlock, la funzione di acquisizione/rilascio era circa il 40% più veloce rispetto alla versione sequenzialmente coerente. enter image description here

+0

L'articolo è molto carino. D'altra parte, sembra sostenere che il divario tra sc e acq-rel è (almeno in questo esempio) puramente dovuto alla compilazione pigra, poiché con il compilatore proposto passa in posizione, il gap sopra è sostanzialmente eliminato, giusto? – user2949652

+0

È passato un po 'di tempo da quando mi sono immerso in questo, ma per quanto mi ricordo il divario tra sc e acq-rel è (in questo esempio) a causa della mancanza di ottimizzazioni del compilatore (prima che la patch menzionata nel repository GitHub fosse aggiunta a llvm) , perché in questo esempio, nel modello di memoria ARM, acq-rel offre le stesse garanzie di sc (di nuovo: nell'esempio fornito, nel modello di memoria ARM, pre-llvm-patch). In nessun modo sto cercando di sostenere che sc e acq-rel dovrebbero essere altrettanto veloci nel caso generale. – Claude

0

Per un particolare pezzo di codice (un dequeue lavoro furto), ho trovato un bel paper che benchmark una versione C11 con Atomics deboli, con sc-Atomics solo, assemblaggio ottimizzato a mano, e un errato versione che utilizza atomici completamente rilassati. (Per coincidenza, un bug è stato successivamente trovato nella versione C11 dal già citato CDSChecker.) Esempi simili sono i benvenuti.