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:
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 cheB=1
non verrà scritto nella cache prima di ?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
Anche se x86 lo garantisce, perché correre il rischio? Perché non usare solo le barriere giuste? –
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
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