2012-01-15 6 views
5

Supponiamo che ci siano due thread in esecuzione su CPU x86 e CPU1 rispettivamente. Discussione in esecuzione su CPU0 esegue i seguenti comandi:Sono due depositi di CPU conseguenti su x86 scaricati nella cache mantenendo l'ordine?

A=1 
B=1 

linea di cache contenente un inizialmente di proprietà di CPU1 e che contiene B di proprietà di CPU0.

Ho due domande:

  1. Se ho capito bene, entrambi i negozi saranno messi in buffer di vendite di CPU. Tuttavia, per il primo archivio la cache di CPU1 deve essere invalidata mentre il secondo archivio B=1 può essere svuotato immediatamente poiché CPU0 possiede la linea cache che lo contiene. So che la CPU x86 rispetta gli ordini del negozio. Significa che B=1 non verrà scritto nella cache prima di ?

  2. assumere in CPU1 vengono eseguiti i seguenti comandi:

mentre (B = 0);
stampa Un

È sufficiente aggiungere solo lfence tra le while e print comandi in CPU1 senza aggiungere uno sfence tra A=1 e B=1 in CPU0 per ottenere 1 sempre stampati su x86?

while (B=0); 
lfence 
print A 
+0

Anche se x86 lo garantisce, perché correre il rischio? Perché non usare solo le barriere giuste? –

+1

Zan, può essere vantaggioso in molti punti se la CPU lo garantisce. Ad esempio, gli spinlock sono implementati senza utilizzare prefissi di blocco nel kernel perché possono permetterselo. E la recinzione non è la soluzione a questa domanda altrimenti, è necessario utilizzare un blocco adeguato. – Saurabh

+0

La risposta alla ** 1-domanda - Sì **. La risposta alla domanda ** 2-nd - Sì, ma solo in assembler (non in C/C++) **. Come giustamente detto, 'LFENCE' qui non è necessario su x86 - fornisce automaticamente coerenza. Si noti che la CPU x86 non può riordinare 'load' e le successive istruzioni, ma C/C++ può riordinarlo. Su C++ si usa * acquisizione consistenza **: 'extern std :: atomico B;' 'while (B.load (std :: memoria_order_acquire) == 0);' 'std :: cout << A;' http://en.cppreference.com/w/cpp/atomic/memory_order – Alex

risposta

8

In x86, le scritture da un singolo processore vengono osservate nello stesso ordine da tutti i processori. Non c'è bisogno di recintare il tuo esempio, né in alcun programma normale su x86. Il tuo programma:

while(B==0); // wait for B == 1 to become globally observable 
print A;  // now, A will always be 1 here 

Ciò che accade esattamente nella cache è specifico del modello. Tutti i tipi di trucchi e comportamenti speculativi possono verificarsi nella cache, ma il comportamento osservabile segue sempre le regole.

Vedere la Guida alla programmazione dei sistemi Intel Volume 3 sezione 8.2.2. per i dettagli sull'ordinazione della memoria.