Domanda

C ++ 0x proposta sui Tipi C ++ atomici e operazioni:

  

29,1 Ordine e coerenza [atomics.order]

     

Aggiungi un nuovo sub-clausola con i paragrafi seguenti.

     

L'enumerazione memory_order specifica il dettaglio di regolare (non-atomico) ordine sincronizzazione memoria, come definito in [nuova sezione aggiunta da N2334 o suo successore adottata] e può prevedere il funzionamento ordinazione. I suoi valori enumerati ed i loro significati sono i seguenti.

     
      
  • memory_order_relaxed
  •   
     

L'operazione non fa memoria di ordine.

     
      
  • memory_order_release
  •   
     

esegue un'operazione di rilascio delle sedi di memoria interessate, rendendo memoria regolare scrive visibile ad altri fili attraverso la variabile atomico a cui è applicato.

     
      
  • memory_order_acquire
  •   
     

esegue un'operazione acquisire delle sedi di memoria interessate, rendendo così scrive memoria regolari in altri thread rilasciato attraverso la variabile atomico a cui è applicato, visibile al thread corrente.

     
      
  • memory_order_acq_rel
  •   
     

L'operazione ha sia la semantica acquisire e di rilascio.

     
      
  • memory_order_seq_cst
  •   
     

L'operazione ha sia semantica acquisire e rilascio, e in aggiunta, ha funzionamento sequenziale-coerente ordinamento.

Bassa nella proposta:

bool A::compare_swap( C& expected, C desired,
        memory_order success, memory_order failure ) volatile
     

dove si può specificare l'ordine di memoria per il CAS.


La mia comprensione è che “memory_order_acq_rel” non farà che necessariamente sincronizzare le locazioni di memoria che sono necessari per l'operazione, mentre le altre posizioni di memoria possono restare non sincronizzato (non si comporterà come un recinto di memoria).

Ora, la mia domanda è - se scelgo “memory_order_acq_rel” e applico compare_swap ai tipi integrali, per esempio, numeri interi, come è questo di solito tradotto in codice macchina su moderni processori di consumo come un multicore Intel i7? Che dire delle altre architetture comunemente usati (x64, SPARC, ppc, braccio)?

In particolare (assumendo un compilatore concreta, dire gcc):

  1. Come confrontare-e-swap una posizione intero con l'operazione di cui sopra?
  2. Quale sequenza di istruzioni sarà una simile produrre codice?
  3. è l'operazione su i7-libera della serratura?
  4. Può tale operazione eseguire un protocollo completo coerenza cache, sincronizzando cache dei diversi processori core come se fosse una recinzione memoria i7? O sarà semplicemente sincronizzare le posizioni di memoria necessari per questa operazione?
  5. Related alla domanda precedente - non v'è alcun vantaggio prestazionale di utilizzare la semantica acq_rel su i7? Che dire delle altre architetture?

Grazie per tutte le risposte.

È stato utile?

Soluzione

La risposta qui non è banale. Esattamente ciò che accade e ciò che si intende dipende da molte cose. Per conoscenza di base della coerenza della cache / memoria forse i miei messaggi recenti del blog potrebbe essere utile:

Ma a parte questo, vorrei provare a rispondere ad alcune domande. Prima di tutto il sotto istruzione è essere molto promettente per ciò che è supportato.

compare_swap( C& expected, C desired,
        memory_order success, memory_order failure )

Architetture sarà non tutti in grado di implementare questo esattamente come da voi richiesto. Quando si specifica memory_order si specifica come il riordino può funzionare. Per usare le parole di Intel verrà specificando che tipo di recinzione che si desidera, ci sono tre di loro, la recinzione completa, recinzione carico, e conservare recinzione. Solo perché si vuole una particolare recinzione in quella operazione non significa che è supportato, in cui mi auguro che cade sempre di nuovo ad un recinto pieno.

Il compilatore probabilmente utilizzare l'instructuion CMPXCHG per implementare la chiamata. Se è stato specificato qualcosa di diverso rilassato segnerà questo con lock per indicare la funzione dovrebbe essere atomica. Se questo è "libero lock-" dipende molto da ciò che si sta pensando in termini di un "blocco.

In termini di sincronizzazione di memoria è necessario capire come funziona la cache di coerenza (il mio blog può aiutare un po '). Nuove CPU utilizzano un'architettura ccNUMA (precedentemente SMP). In sostanza la "vista" sulla memoria non viene mai out-of-sync. Le recinzioni utilizzate nel codice in realtà non forzare ogni lavaggio per accadere per-sé. Se due nuclei entrambi hanno la stessa posizione di memoria cache in una cache-linea, si otterrà contrassegnata sporco e l'altra ricarica volontà come necessario. Una spiegazione molto semplice per un processo molto complesso

Per rispondere alla tua ultima domanda è necessario utilizzare sempre la semantica di memoria che si logicamente bisogno di essere corretto. La maggior parte delle architetture non supportano tutte le combinazioni che si utilizzano nel programma. Tuttavia, in molti casi, si otterrà grandi ottimizzazioni, soprattutto nei casi in cui l'ordine che avete richiesto è garantita senza una recinzione (che è abbastanza comune).

- le risposte ad alcune osservazioni:

Si deve distinguere tra ciò che significa eseguire un'istruzione di scrittura e scrittura a una posizione di memoria. Questo è ciò che tento di spiegare nel mio post sul blog. Con il tempo la "0" si impegna a 0x100, tutti i core vedere che zero. Scrivendo interi è anche atomica, che è ancora senza un blocco, quando si scrive in una posizione tutti i core avranno immediatamente quel valore se desiderano usarlo.

Il problema è che per usare il valore probabilmente avete caricato in un registro prima, eventuali modifiche alla posizione dopo che, ovviamente, non toccherà il registro. Questo è il motivo per cui si ha bisogno mutex nonostante una memoria cache coerente.

Per quanto riguarda affermazioni contraddittorie, generalmente vedrete tutti i tipi di richieste. Che siano contraddittorie tratta fino ad esattamente ciò che "vedere" "carico" "eseguire" media nel contesto. Se si scrive "1" a 0x100, significa che si esegue l'istruzione di scrittura o fatto la CPU in realtà commettere tale valore. La differenza deriva dal riordino. La CPU può ritardare la scrittura del "1", ma si può essere sicuri che il momento lo fa finalmente commettere che "1" tutti i core vedono. Le recinzioni controllano questo ordinamento.

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