utilizzo di Interlocked.Exchange per l’aggiornamento delle referenze e Int32

e ‘noto che un riferimento prende 4 Bytes di memoria in processore a 32 bit e 8 Bytes – in processore a 64 bit. così, i processori garantiscono che singole letture da e scrive a memoria in incrementi della dimensione naturale parola della macchina sarà effettuata atomicamente. d’altra parte ci sono 2 metodi in classe interbloccata:

public static int Exchange(
    ref int location1,
    int value
)

e e e e e

public static T Exchange<T>(
    ref T location1,
    T value
)
where T : class

quindi, la domanda è perché Interlocked.Exchange è necessario per Int32 e per i tipi di riferimento? non potrebbe essere fatto in modo sicuro utilizzando solo di semplice assegnazione perché è atomica?

EN From: Using of Interlocked.Exchange for updating of references and Int32

More similar articles:

16 Comments

  1. lo scambio di un valore di memoria ed il contenuto di un registro della CPU non è in generale atomico. entrambi avete bisogno di leggere e scrivere la posizione della memoria. inoltre, i metodi Interlocked garantisce che l’operazione è atomica anche su computer multi-core in cui ogni nucleo ha la propria cache e potenzialmente la propria vista della memoria principale.

    1. ma se non ho bisogno di avere vecchio valore e voglio solo assegnare nuovo valore ad alcune variabili. questo è solo scrittura e atomica, giusto?

    2. @OlegDudnyk Penso che non sia corretto, anche voi non si preoccupano valore originale. considerate come raggiungere questo obiettivo nel linguaggio assembly, dipende da dove sono le vostre variabili / valore src e dest, potrebbero essere tradotte in più di una istruzione, tra 2 istruzioni la vostra applicazione può ancora essere interrotta. su alcune architetture è possibile bloccare il bus per assicurarsi che nessuno possa leggere la memoria di scrittura (ad esempio ia ha il prefisso LOCK, e alcune istruzioni sono garantite per essere atomica (ad esempio XCHG, CMPXCHG, ecc,. su IA).

  2. Interlocked.Exchange ha un valore di ritorno, che consente di sapere quale valore appena sostituito. e ‘la combinazione di impostare un nuovo valore e ottenere il vecchio valore che questi metodi raggiungere.

    1. quindi, se non hai bisogno del vecchio valore che potresti semplicemente assegnare, ma allora avresti anche bisogno di una chiamata Barrier per invalidare la cache (s).

  3. Interlock.Exchange restituisce il valore originale durante l’esecuzione di un’operazione atomica. il punto è quello di fornire un meccanismo di bloccaggio. così è in realtà due operazioni: leggere il valore originale e impostare nuovo valore. questi due insieme non sono atomici.

    1. ma se non ho bisogno di avere vecchio valore e voglio solo assegnare nuovo valore ad alcune variabili. questo è solo scrittura e atomica, giusto?

  4. non si tratta solo di atomicità. si tratta anche di visibilità della memoria. la variabile può essere memorizzata nella memoria principale o nella cache della CPU. se la variabile è memorizzata solo nella cache della CPU non sarà visibile ai thread in esecuzione su CPU diverse. consideriamo il seguente esempio:

    public class Test {
        private Int32 i = 5;
    
        public void ChangeUsingAssignment() {
            i = 10;
        }
    
        public void ChangeUsingInterlocked() {
            Interlocked.Exchange(ref i, 10);
        }
    
        public Int32 Read() {
            return Interlocked.CompareExchange(ref i, 0, 0);
        }
    }

    ora, se chiamate ‘ChangeUsingAssignment’ su un thread e ‘Read’ su un altro thread, il valore di ritorno potrebbe essere 5, non 10. ma se chiami ChangeUsingInterlocked, ‘Read’ restituirà 10 come previsto.

     ----------         ------------         -------------------
    |   CPU 1  |  -->  |   CACHE 1  |  -->  |                   |
     ----------         ------------        |                   |
                                            |        RAM        |
     ----------         ------------        |                   |
    |   CPU 2  |  -->  |   CACHE 2  |  -->  |                   |
     ----------         ------------         -------------------

    nel diagramma qui sopra il metodo ‘ChangeUsingAssignement’ può risultare che il valore 10 venga ‘bloccato’ in CACHE 2 e non lo faccia alla RAM. quando CPU 1 successivamente cerca di leggerlo, otterrà il valore dalla RAM dove è ancora 5. utilizzando interlocked invece di scrittura ordinaria farà in modo che il valore 10 arriva fino alla RAM.

    1. hai ragione per la visibilità della memoria, ma la tua spiegazione non è corretta. una volta che il valore entra nella cache del processore è visibile a tutti i core della CPU fisica. questo è garantito da https://en.wikipedia.org/wiki/Cache_coherence.

      il problema con la visibilità della memoria è quando i valori sono ancora nei buffer di lettura / scrittura all’interno del core della CPU (che non è CPU L1, L2, L3 cache)

Leave a Reply

Your email address will not be published. Required fields are marked *