Perché lo stato condiviso peggiora le prestazioni?

19

Ho lavorato sotto il principio "share-nothing" della programmazione concorrente. In sostanza, tutti i miei thread di lavoro hanno immutabili copie di sola lettura dello stesso stato che non sono mai condivise tra loro ( anche per riferimento ). In generale, questo ha funzionato molto bene.

Ora, qualcuno ha introdotto una cache singleton senza blocco ( ad esempio un dizionario statico ) a cui tutti i thread stanno accedendo contemporaneamente. Poiché il dizionario non viene mai modificato dopo l'avvio, non ci sono blocchi. Non ci sono stati problemi di sicurezza dei thread, ma ora c'è un degrado delle prestazioni.

La domanda è ... dato che non ci sono serrature perché l'introduzione di questo singleton crea un successo nelle prestazioni? Cosa sta succedendo esattamente sotto le coperte che potrebbe spiegare questo?

Per confermare, l'accesso a questo nuovo singleton è l'unica modifica e posso ricreare in modo affidabile questo semplicemente commentando la chiamata alla cache.

    
posta JoeGeeky 15.12.2011 - 20:35
fonte

2 risposte

8

Potrebbe essere che lo stato immutabile condivide una linea di cache con qualcosa di mutabile. In questo caso, una modifica allo stato mutabile vicino potrebbe avere l'effetto di forzare una risincronizzazione di questa linea di cache attraverso i core, il che potrebbe rallentare le prestazioni.

    
risposta data 15.12.2011 - 22:44
fonte
3

Mi assicurerei che i metodi Equals() e GetHashCode() degli oggetti che usi come chiavi per il dizionario non abbiano effetti collaterali imprevisti non favorevoli alla filettatura. Il profiling sarebbe di grande aiuto qui.

Se per caso le tue chiavi sono stringhe, allora forse ce l'hai: la voce dice che le stringhe si comportano come oggetti immutabili ma per il bene di certe ottimizzazioni sono implementate internamente in modo mutevole, con tutto ciò che questo comporta con rispetto al multithreading.

Vorrei provare a passare il dizionario ai thread che lo usano come riferimento regolare invece di un singleton per vedere se il problema sta nella condivisione o nella singolarità del dizionario. (Eliminazione delle possibili cause).

Vorrei anche provare con un ConcurrentDictionary invece di un normale Dictionary nel caso in cui il suo utilizzo produca risultati sorprendenti. Ci sono molte cose da speculare sul problema in questione se un ConcurrentDictionary risulta performante molto meglio o molto peggio del normale Dictionary .

Se nessuno dei precedenti punti al problema, allora suppongo che le prestazioni degradate siano causate da qualche strano tipo di conflitto tra il thread di raccolta dei rifiuti e il resto dei thread, come il garbage-collector sta provando a capire se gli oggetti nel tuo dizionario devono essere eliminati o meno, mentre sono accessibili dai tuoi thread.

    
risposta data 16.12.2011 - 21:55
fonte

Leggi altre domande sui tag