Domanda

Diciamo che ho una struct che consistono di 100 byte. Che garanzie ho ottenuto circa il seguente codice?

m_myLargeStruct = someValue; // copying 100 bytes
Thread.MemoryBarrier();

// Executed by another thread, after "Thread.MemoryBarrier" was called by the first thread
Console.WriteLine(m_myLargeStruct.ToString());

Il modello di garanzia di memoria che i 100 byte copia sarà completata dopo il posizionamento della barriera di memoria? o non barriere di memoria si applicano solo per i tipi che sono alla dimensione dell'architettura del processore? (4 byte per 32bit e 8 byte a 64 bit).
E 'questa la ragione per cui il volatili parola chiave si applica solo per i tipi primitivi? (Se dichiaro un membro di 8 byte come volatile, ciò significa che un instrinct interbloccata verrà utilizzato per modificare il suo valore? [Poiché atomicity non è garantita per tipi maggiori di 4 byte su macchine 32bit]).

Spero di essere stato abbastanza chiaro .. :)
Grazie

È stato utile?

Soluzione

Chiaramente la risposta è non , o meglio, non hai garanzie di nulla. Nulla impedisce al sistema operativo di scambio fuori il filo che sta scrivendo nella struct 100 byte prima di iniziare il filo che stampa lo struct 100 byte.

Una barriera di memoria viene utilizzato quando si vuole coordinare l'accesso ai dati tramite una bandierina o qualche altro valore atomico. Non so che cosa esattamente si sta cercando di fare, quindi non posso dare un buon codice di esempio su come si dovrebbe fare.

Altri suggerimenti

A meno che il filo di lettura ha una barriera di memoria troppo, io non pensare che ti aiuto molto.

Personalmente mi sento di rifuggire da:

  • Structs che sono quel grande
  • Come profondamente nel modello di memoria scrivere codice senza blocchi

... a meno che non si dispone di un motivo molto importante per farlo. E ' enormemente duro per ottenere la codifica senza blocchi a destra con i dati mutabile; Credo che anche gli esperti lottano. Io di solito trovo che il "prendere un blocco fuori per ogni blocco di accesso ai dati" l'approccio è più facile da ottenere il diritto e va bene in termini di prestazioni per il 99% dei casi.

ho fiducia nella squadra PFX a Microsoft per ottenere senza blocchi codifica a destra, e per loro di fornire me con incantevoli modi posso usare il loro codice per scrivere i miei programmi gratuiti proprio di blocco in modo relativamente semplice. Non mi fido di me stesso per ottenere questo tipo di cosa giusta. Se mai bisogno di utilizzare in modo esplicito una barriera di memoria, che probabilmente significa che sto cercando troppo duro.

È necessario un'altra barriera di memoria nel secondo thread, prima di WriteLine. (Se il sistema fornisce le barriere di memoria asimmetriche, è sufficiente per eseguire una barriera di uscita dopo l'assegnazione e una barriera Acquisire prima WriteLine).

Le dimensioni dei dati non ha importanza.

Hai bisogno di una barriera di memoria in entrambi i luoghi / discussioni, e naturalmente è necessario un qualche tipo di sincronizzazione tra i due in modo barriera della 2 ° del thread non ottiene 'run' prima della prima del thread.

In particolare, il filo scrittura ha bisogno di una barriera memoria 'rilascio', e il filo di lettura ha bisogno di una barriera memoria 'acquisire' (se la piattaforma sottostante supporta la semantica barriera separate).

A meno che non si sta chiedendo per curiosità accademica o si sta scrivendo il proprio quadro, si dovrebbe davvero basta usare un oggetto di sincronizzazione dalla libreria / quadro / piattaforma. Cercando di ottenere tutta questa roba corretta è difficile, ed è già fatto negli oggetti di sincronizzazione forniti.

Beh, prima di tutto quello che non dovrebbe avere una struttura che è molto grande. A meno che non vi sono estremamente attenti a come si utilizza lo struct, sarà più lento rispetto all'utilizzo di una classe. Inoltre, è controintuitivo alla semantica di valore di strutture.

Detto questo, la barriera di memoria garantirà che la struct viene copiato. L'ottimizzazione non si muove tutte le istruzioni attraverso la barriera.

La parola chiave volatile è un po 'diverso. Garantisce che nessuna operazione contro la variabile è ottimizzato via, e lo fa garantire l'ordine di accessi alla memoria. Tuttavia, per i tipi di dati che non è possibile accedere in modo atomico, è per lo più inutili ai fini threading, come si può ancora leggere la metà di un nuovo valore e la metà di un vecchio valore.

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