È stato utile?

Soluzione

"JDK-6.275.329: Aggiungere metodi lazySet alle classi atomiche" :

  

Come probabilmente l'ultimo piccolo JSR166 follow-up per la Mustang,   abbiamo aggiunto un metodo "lazySet" per le classi Atomic   (AtomicInteger, AtomicReference, ecc). Si tratta di una nicchia   metodo che a volte è utile quando il codice messa a punto utilizzando   non bloccante strutture di dati. La semantica è   che la scrittura è garantito di non essere ri-ordinati con qualsiasi   precedente scrittura, ma possono essere riordinate operazioni successive   (O equivalentemente, potrebbe non essere visibile ad altri thread) fino   si verifica qualche altro scrittura volatile o azione sincronizzazione).

     

Il caso d'uso principale è per annullamento dei fuori campi di nodi   non bloccante strutture dati unicamente a fini di evitare   A lungo termine la conservazione della spazzatura; si applica quando è innocuo   se altri thread vedono valori non nulli per un po ', ma si sarebbe   come per garantire che le strutture sono infine GCable. in tale   i casi, è possibile ottenere prestazioni migliori, evitando   i costi della nullo volatili-scrittura. Ci sono alcuni   altri casi di utilizzo in tal senso per non riferimento basati   Atomics pure, in modo che il metodo è supportato in tutte le   classi AtomicX.

     

Per le persone che amano pensare di queste operazioni in termini di   barriere a livello macchina su multiprocessori comuni, lazySet   fornisce una barriera negozio negozio precede (che è o   un no-op o molto a buon mercato su piattaforme attuali), ma non   barriera negozio carico (che di solito è la parte costosa   di volatili-scrittura).

Altri suggerimenti

lazySet possono essere utilizzati per la comunicazione filo tra RMW, perché xchg è atomico, come per la visibilità, quando processo thread di scrittura modificare una posizione linea di cache, il processore del filo lettore vedrà alla lettura successiva, perché il protocollo coerenza della cache di Intel CPU la garanzia funziona LazySet, ma la linea di cache verrà aggiornato alla prossima lettura, ancora una volta, la CPU deve essere abbastanza moderno.

http://sc.tamu.edu/systems/eos/nehalem.pdf Nehalem che è una piattaforma multi-processore, i processori hanno la capacità di “snoop” (intercettare) il bus domicilio altro processore di accessi alla memoria di sistema e alle loro cache interne. Usano questa capacità snooping per mantenere le loro cache interne coerente sia con la memoria di sistema e con le cache in altri processori interconnessi. Se attraverso snooping un processore rileva un altro processore si propone di scrivere in una posizione di memoria che attualmente è nella cache a stato condiviso, il processore snooping invaliderà il suo blocco di cache costringendolo a eseguire una linea di cache riempire la prossima volta che si accede alla stessa posizione di memoria .

Oracle JDK hotspot per l'architettura cpu x86 ->

lazySet == == unsafe.putOrderedLong xchg RW (istruzione asm che servono da barriera morbido costano 20 cicli su nehelem Intel CPU)

su x86 (x86_64) una tale barriera è molto più conveniente prestazioni-saggio di volatili o AtomicLong getAndAdd,

In un un produttore, uno scenario di coda dei consumatori, XCHG barriera morbido può forzare la linea di codici prima della lazySet (sequenza + 1) per filo produttore accadere prima alcun codice discussione consumatore che consumerà (lavoro sopra) i nuovi dati Naturalmente filo consumatore dovrà controllare atomicamente quella sequenza produttore è stato incrementato di esattamente un utilizzando un compareAndSet (sequenza, la sequenza + 1).

Ho tracciato dopo il codice sorgente di Hotspot per trovare l'esatta mappatura del lazySet in codice cpp: http: // hg.openjdk.java.net/jdk7/jdk7/hotspot/file/9b0ca45cd756/src/share/vm/prims/unsafe.cpp Unsafe_setOrderedLong -> definizione SET_FIELD_VOLATILE -> OrderAccess: release_store_fence. Per x86_64, OrderAccess: release_store_fence è definito come utilizzando l'istruzione xchg.

Si può vedere come è esattamente definito in jdk7 (Doug Lea sta lavorando su del nuovo materiale per JDK 8): http: //hg.openjdk.java.net/jdk7/jdk7/hotspot/file/4fc084dac61e/src/os_cpu/linux_x86/vm/orderAccess_linux_x86.inline.hpp

è anche possibile utilizzare i ISU di smontare il montaggio del codice di lazySet in azione.

C'è un'altra domanda relativa: abbiamo bisogno mfence quando si utilizza xchg

Una più ampia discussione sulle origini e l'utilità del lazySet e putOrdered sottostante può essere trovato qui: http://psy-lob-saw.blogspot.co.uk/2012/12/atomiclazyset-is-performance-win-for.html

Riassumendo: lazySet è una scrittura volatile, debole nel senso che agisce come un negozio negozio e non una recinzione store-carico. Questo si riduce a lazySet essere JIT compilato per un'istruzione MOV che non può essere ri-ordinato dal compilatore piuttosto che l'istruzione notevolmente più costoso utilizzate per un insieme volatile.

Quando si legge il valore si finisce sempre per fare una lettura volatile (con un Atomic * .get () in ogni caso).

lazySet offre un unico produttore di un meccanismo di scrittura volatili coerente, vale a dire che è perfettamente legittimo per un singolo scrittore di utilizzare lazySet per incrementare un contatore, più thread incrementando il contatore stesso dovranno risolvere le scritture concorrenti che utilizzano CAS, che è esattamente cosa succede sotto le coperte di Atomic * per incAndGet.

Concurrent- atomico sintesi pacchetto

lazySet ha gli effetti di memoria di scrittura (assegnazione) una variabile volatile, con la differenza che permette reorderings con successive (ma non precedenti) azioni di memoria che non ci incalzano vincoli riordino con le scritture non volatili ordinarie . Tra gli altri contesti di utilizzo, lazySet può applicare quando annullamento dei out, per il bene di garbage collection, un riferimento che non è mai accedere nuovamente.

Se siete curiosi di sapere lazySet allora lo dovete voi stessi altre spiegazioni troppo

  

Gli effetti di memoria per gli accessi e gli aggiornamenti di Atomics in generale   seguire le regole di volatili, come indicato nella sezione 17.4 di The Java ™   Specifica del linguaggio.

     

ha gli effetti di memoria di lettura di una variabile volatile.

     

set ha gli effetti di memoria di scrittura (assegnazione) una variabile volatile.

     

lazySet ha gli effetti di memoria di scrittura (assegnazione) una variabile volatile, eccetto che permette reorderings con successive (ma non precedenti) azioni di memoria che non ci incalzano riordino   vincoli con le scritture non volatili ordinari. Tra l'altro l'uso   contesti, lazySet si possono verificare quando annullamento dei out, per il bene della spazzatura   collezione, un riferimento che non è mai accedere nuovamente.

     

weakCompareAndSet si legge atomico e il condizionale scrive una variabile ma non crea alcun accade-prima ordinamenti, lo prevede   nessuna garanzia rispetto al precedente o successiva letture e le scritture   di tutte le variabili diverse dalla destinazione del weakCompareAndSet.       operazioni compareAndSet e tutti gli altri lettura e-aggiornamento come getAndIncrement hanno gli effetti di memoria di lettura e scrittura   variabili volatili.

Questa è la mia comprensione, mi corregga se sbaglio: Si può pensare lazySet() come "semi" volatile: è fondamentalmente una variabile non volatile in termini di lettura di altri thread, cioè il valore impostato dal lazySet non può essere visibile ad altri thread. Ma diventa instabile quando si verifica un'altra operazione di scrittura (può essere da altri thread). L'unico impatto della lazySet posso immaginare è compareAndSet. Quindi, se si utilizza lazySet(), get() da altri thread può ancora ottenere il vecchio valore, ma compareAndSet() avrà sempre il nuovo valore in quanto si tratta di un'operazione di scrittura.

Re: tentativo di muto giù -

Si può pensare a questo come un modo per trattare un campo volatile, come se non fosse stato volatile per un particolare negozio (ad esempio: ref = null;). Operazione

Non è perfettamente accurata, ma dovrebbe essere sufficiente che si potrebbe prendere una decisione tra "OK, io davvero non mi interessa" e "Hmm, fammi pensare che per un po '".

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top