Domanda

È necessario preoccuparsi delle MemoryBarrier quando si utilizzano le estensioni parallele?

Modifica: per elaborare poiché la domanda originale era a risposta aperta:La risposta di (@xanatos era quella che cercavo)

Per fare un esempio concreto:presumo di utilizzare Parallel.ForEach e ogni iterazione imposta il valore di una proprietà all'interno della classe (ogni iterazione imposta la propria proprietà specifica, non esistono due iterazioni che impostano il valore della stessa proprietà).Nello stesso thread che ha chiamato Parallel.ForEach, accedo alle proprietà impostate da Parallel.ForEach.

class Program
{
  static void Main(string[] args)
  {
    var t = new Test();
    t.InitializePropertiesInParallel();
    var a = t.PropA; // Could never be 0?
    var b = t.PropB; // Could never be 0?
  }
}

public class Test
{
  public int PropA { get; set; }
  public int PropB { get; set; }

  public void InitializePropertiesInParallel()
  {
    var initializers = new List<Action<int>>()
    {
      i => PropA = i,
      i => PropB = i
    };

    initializers.AsParallel().ForAll(a => a(1));
  }
}
È stato utile?

Soluzione

Se ogni lavoratore non ha bisogno dei dati preparati dagli altri lavoratori (quindi non c'è alcuna situazione in cui il lavoratore 1 scrive A e il lavoratore 2 legge A) non è necessario MemoryBarrier.Quando tutte le attività finiscono c'è un Wait che agisce come a MemoryBarrier (alla fine, anche se non lo vedi, da qualche parte c'è un costrutto di sincronizzazione che aspetta che tutti i lavoratori finiscano)

Altri suggerimenti

Tieni presente una cosa qui: Invalidazione della linea della cache.È un argomento complicato, ma c'è un ottimo articolo MSDN su di esso qui .

GIST di esso in questo particolare esempio è che, perché stai modificando la stessa istanza dell'oggetto da due file diversi, anche se non si tocca la stessa identica posizione in memoria, si sta per toccare la stessa linea di cacheE così quando il primo thread sul processore 1 cambia la memoria, la cache verrà scaricata e aggiornata prima che il processore 2 possa leggere / scrivere di nuovo.

Detto questo, di nuovo considerando il tuo esempio specifico con solo due oggetti di scena, questa è una micro-ottimizzazione e assolutamente non qualcosa di cui preoccuparsi.Solo qualcosa per essere consapevole se dovessi estrapolare su di esso.

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