Sto provando a creare una versione stupida di uno spin lock. Navigando sul web, mi sono imbattuto in un'istruzione di assemblaggio chiamata "PAUSE" in x86, che è usata per dare un suggerimento a un processore su cui è attualmente in esecuzione uno spin-lock su questa CPU. Il manuale Intel e informazioni di stato disponibili cheQual è lo scopo dell'istruzione "PAUSE" in x86?
Il processore utilizza questo suggerimento per evitare la violazione dell'ordine memoria maggior parte delle situazioni, che migliora notevolmente le prestazioni del processore. Per il motivo , si consiglia di inserire un'istruzione PAUSE in tutti i cicli di attesa di spin. La documentazione menziona anche che "wait (some delay)" è la pseudo implementazione dell'istruzione.
L'ultima riga del paragrafo precedente è intuitiva. Se non riesco ad afferrare il lucchetto, devo aspettare un po 'prima di afferrare di nuovo il lucchetto.
Tuttavia, che cosa intendiamo per violazione di ordine di memoria in caso di spin lock? Per "violazione dell'ordine di memoria" si intende l'errato speculativo carico/archivio delle istruzioni dopo spin-lock?
La domanda spin-lock è stata chiesta su Stack overflow before ma la domanda di violazione dell'ordine di memoria rimane senza risposta (almeno per la mia comprensione).
(+1) Grazie per l'ottima risposta! Quello che non capisco pienamente è che cosa rende un gasdotto un costo così importante in questa situazione, dato che tutte quelle letture speculative e i rami condizionali presi speculativamente sono assolutamente inutili comunque? Inoltre, c'è un modo per quantificare il costo del flush? – NPE
@NPE Il tempo di recupero da un flush dipende dalla microarchitettura. Processori con pipeline più lunghe (come Core 2) ovviamente soffrono più di quelli con pipeline più brevi (come Atom). Tuttavia, nel caso di un processore con hyperthreading tutte le istruzioni "inutilmente" eseguite rimuovono risorse dall'altro thread sullo stesso core. L'istruzione PAUSE essenzialmente cede la cpu all'altro thread. Pertanto, mentre il costo per il thread bloccato è "solo", due flussi di pipeline, il costo per l'altro thread può essere molto più significativo (a seconda di quanto tempo è trascorso all'interno del blocco). –
Poiché le istruzioni CMP (2) vengono eseguite in sequenza, è improbabile (ovvero la finestra temporale è molto più breve) che una scrittura esterna si verifica dopo che l'istruzione CMP (2) ha letto lockvar ma prima che il CMP sia impegnato. Potresti spiegarlo per favore? Cosa intendi per commit? – KodeWarrior