Domanda

In quali circostanze non è sicuro avere due thread diversi che scrivono contemporaneamente su elementi adiacenti dello stesso array su x86? Capisco che su alcune architetture simili a DS9K con modelli di memoria folle ciò può causare lo strappo delle parole, ma su x86 singoli byte sono indirizzabili. Ad esempio, nel linguaggio di programmazione D real è un tipo a virgola mobile a 80 bit su x86. Sarebbe sicuro fare qualcosa del tipo:

real[] nums = new real[4];  // Assume new returns a 16-byte aligned block.
foreach(i; 0..4) {
    // Create a new thread and have it do stuff and 
    // write results to index i of nums.
}

Nota: so che, anche se è sicuro, a volte può causare falsi problemi di condivisione con la cache, con conseguente rallentamento delle prestazioni. Tuttavia, per i casi d'uso che ho in mente, le scritture saranno abbastanza rare da non importare nella pratica.

Modifica: non preoccuparti di rileggere i valori scritti. Il presupposto è che sarà sincronizzato prima di leggere qualsiasi valore. Mi preoccupo solo della sicurezza di scrivere in questo modo.

È stato utile?

Soluzione

L'x86 ha cache coerenti. L'ultimo processore per scrivere su una riga della cache acquisisce tutto e fa una scrittura nella cache. Ciò garantisce che i valori a byte singolo e 4 byte scritti sui valori corrispondenti vengano aggiornati atomicamente.

Questo è diverso da " è sicuro " ;. Se i processori scrivono solo in byte / DWORDS "posseduti" da quel processore in base alla progettazione, quindi gli aggiornamenti saranno corretti. In pratica, si desidera che un processore legga i valori scritti da altri e ciò richiede sincronizzazione.

È anche diverso da quello che è "efficiente". Se più processori possono scrivere in posizioni diverse nella riga della cache, allora la riga della cache può eseguire il ping-pong tra le CPU e questo è molto più costoso che se la riga della cache passa a una singola CPU e rimane lì. La regola abituale è quella di mettere i dati specifici del processore nella propria linea di cache. Naturalmente, se hai intenzione di scrivere solo per quella parola, solo una volta, e la quantità di lavoro è significativa rispetto a uno spostamento della linea di cache, quindi la tua esibizione sarà accettabile.

Altri suggerimenti

Potrei mancare qualcosa, ma non prevedo alcun problema. L'architettura x86 scrive solo ciò di cui ha bisogno, non esegue alcuna scrittura al di fuori dei valori specificati. Lo snooping della cache gestisce i problemi della cache.

Stai chiedendo informazioni su x86, ma il tuo esempio è in un linguaggio di alto livello. La tua domanda specifica su D può essere risolta solo dalle persone che hanno scritto il compilatore che stai utilizzando, o forse dalle specifiche del linguaggio D. Java, ad esempio, richiede che l'accesso agli elementi dell'array non debba causare strappi.

Per quanto riguarda x86, l'atomicità delle operazioni è specificata nella Sezione 8.1 del Manuale per gli sviluppatori di software Intel Volume 3A . Secondo esso, le operazioni di memorizzazione atomica includono: memorizzazione di un byte, memorizzazione di parole allineate a parola e parole allineate a parola su tutte le CPU x86. Specifica inoltre che su CPU P6 e successive l'accesso disallineato a 16, 32 e 64 bit alla memoria cache all'interno di una linea di cache è atomico.

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