In che modo lo spinlock è diverso dal polling?


41

Spinlock e polling sono la stessa cosa?

Wikipedia:

uno spinlock è un lock che fa sì che un thread che tenta di acquisirlo attenda semplicemente in un loop ("spin") mentre controlla ripetutamente se il lock è disponibile

Sembra tremendamente simile a:

while(!ready);

Mi è stato insegnato a evitare il polling ogni volta che era possibile, dato che era del tutto non ottimale. Quindi, spinlock è un nome di fantasia per il vecchio polling? In che modo uno spinlock è diverso dal polling?

Risposte:


85

Il polling si riferisce al controllo ripetuto della disponibilità di una risorsa ( qualsiasi tipo di risorsa).

Uno spinlock è quando la risorsa di cui si esegue il polling è un blocco.

Si noti che il polling non è male. In particolare, il polling è efficace quando di solito sono disponibili dati pronti per il polling. Il polling è inefficiente solo se lo fai senza poi ottenere alcun dato in cambio.

D'altra parte, gli interrupt sono inefficienti se ci sono così tanti dati da essere costantemente interrotti. Sono efficienti se i dati arrivano abbastanza raramente da poter effettivamente svolgere un lavoro utile prima di essere interrotti.

Posso darti un esempio di vita reale per esperienza personale: 15 anni fa, avevo impostato il mio programma di posta elettronica per interrompermi ogni volta che arrivava una nuova e-mail. Che avveniva una o due volte alla settimana. Controllare costantemente la mia casella di posta sarebbe stata una perdita di tempo colossale.

Oggi ho disattivato tutte le notifiche. Io so che ogni volta che guardo la mia casella di posta, ci saranno nuove email lì. Il polling è molto più efficiente ora.

Gli spinlock sono efficienti quando a) la probabilità che il blocco venga preso è bassa eb) se il blocco viene preso, verrà trattenuto solo per un breve periodo. In altre parole: è efficace per serrature a grana fine per lo più non contese, ma inefficiente per serrature a grana grossa altamente contese.

(E, naturalmente, gli spinlock funzionano solo quando c'è un vero parallelismo, altrimenti l'altro thread non avrà la possibilità di rilasciare il lock. Immagino che sia abbastanza ovvio, ma volevo dichiararlo comunque.)


5
Gli spinlock possono essere perfettamente sensibili in un ambiente cooperativo multitasking. Devi solo assicurarti di cedere il controllo nel loop.
Kevin,

4
Ottimo esempio con le e-mail. Mi ricorda che hai sempre un'e-mail ...
Petr Pudlák,

2
@Kevin: ho un'idea molto puristica di uno spinlock, letteralmente un lucchetto che gira semplicemente in un loop vuoto. ( atomically_do { while (lock.is_locked?); lock.acquire! }) Se cede, non è un anello vuoto e quindi non una svolta in quella visione puristica MrGreen Ma ovviamente una certa ibridazione con altri tipi di serrature o rilassamenti / aggiunte all'ideale platonico ha perfettamente senso nel mondo reale.
Jörg W Mittag,

3
@bubakazouba: uno spinlock funziona letteralmente "ruotando" in un loop vuoto e controllando "Il blocco è ancora rilasciato? Il blocco è ancora rilasciato? Il blocco è ancora rilasciato? Il blocco è ancora rilasciato? Il blocco è ancora rilasciato?" ancora e ancora. Se non c'è parallelismo, allora non c'è nessun altro thread in esecuzione allo stesso tempo che potrebbe rilasciare il blocco, quindi hai effettivamente un loop infinito! Vedi il commento direttamente sopra il tuo.
Jörg W Mittag,

1
@kasperd: è ancora possibile vedere il multitasking cooperativo nel software server guidato da eventi come nginx. In quel caso, c'è un thread e nessun blocco, il che significa che puoi sfruttare solo un core. Per quanto ne so, non ci sono letteralmente esempi reali del vero multitasking cooperativo multicore. Un tale sistema sarebbe stupido, dal momento che otterresti tutti gli aspetti negativi del multitasking cooperativo senza il vantaggio di nessuna chiusura.
Kevin,

10

Uno spinlock è un tipo di blocco, in particolare uno ottenuto tramite polling.

Il polling è un metodo per controllare lo stato di qualcosa (chiedendo lo stato, invece di aspettare che gli venga detto lo stato).

Non tutto il polling è uno spinlock, ad esempio il polling dello stato dei tasti della tastiera.


Inoltre, il polling non è intrinsecamente negativo. Periodi di polling molto brevi possono evitare costosi cambiamenti di contesto che richiederebbero l'uso di interrupt, per non parlare del fatto che il polling può talvolta essere più semplice da implementare e quindi più facile da mantenere, specialmente ai livelli più bassi. Come al solito, gli assoluti sono una cosa terribile e dovresti usare il metodo che offre il giusto compromesso prestazioni / complessità per le tue esigenze così come le hai misurate , piuttosto che usare ciecamente o scartare le opzioni.


5

Spinlock è diverso dal polling perché si verifica solo per un periodo di tempo molto breve, nell'ordine di pochi millisecondi o meno. Il polling può continuare all'infinito.

Nella programmazione parallela, un breve episodio di spinning è spesso preferibile al blocco, poiché evita il costo del cambio di contesto e delle transizioni del kernel.

Ulteriori letture
SpinLock e SpinWait in C #
Spinlock e blocchi di lettura / scrittura in C


Penso che intendevi dire microsecondi. Per un blocco che dura un intero millisecondo dovremmo usare un'implementazione del blocco che fa una chiamata del kernel in contesa.
Peter,

@Peter Forse è questo che intendeva Albahari. Questo è ciò che dice il suo testo.
Robert Harvey,

4

La differenza è che uno spinlock viene (si spera) utilizzato solo in situazioni in cui è appropriato e in queste situazioni è molto efficiente.

Si utilizza uno spinlock se si prevede che una risorsa verrà bloccata solo per un tempo molto breve, ad esempio se un blocco viene utilizzato solo per aggiornare una variabile. Lo spinlock esegue il polling del blocco alla massima velocità, ma si spera per meno di microsecondi. Un normale mutex richiederebbe una chiamata al sistema operativo. Se il blocco viene mantenuto solo per una piccola quantità di tempo, lo spinlock utilizza solo una piccola quantità di tempo della CPU, mentre la chiamata del sistema operativo richiederà più tempo. Ma se questa aspettativa è sbagliata, lo spinlock è molto inefficiente: utilizzerà il 100% del tempo della CPU su una CPU, mentre il normale mutex impiega solo il tempo per entrare nel sistema operativo e tornare.

A volte entrambi sono combinati; esegui lo spin lock per un breve periodo e passi a una strategia diversa se lo spinlock non funziona.


2

Il polling eccessivo è qualcosa che non dovresti fare perché spreca risorse di sistema. Ne consegue che il polling va bene se non spreca risorse di sistema .

Ad esempio, un polling eccessivo porterà il carico della CPU al 100% nei casi in cui il lavoro effettivo comporterebbe solo un carico del 2%.

Il polling può essere utilizzato per altro while(!ready). Ad esempio significa controllare regolarmente se l'utente ha premuto un tasto. Un'implementazione sana controllerà al massimo una volta ogni 15 millisecondi, quindi è un controllo ogni ~ 20 milioni di cicli di clock. Questo tipo di polling è eccezionale, perché non spreca risorse di sistema.

Uno SpinLock non è un caso speciale. Se abbiamo un SpinLock e un thread entra nel blocco e un altro deve attendere, SpinLock è la scelta sbagliata se e solo se il thread in attesa spreca risorse di sistema. Il thread in attesa sprecherà risorse di sistema se e solo se deve attendere un periodo di tempo significativo prima di poter acquisire il blocco.

Pertanto, utilizzare uno SpinLock per proteggere tutto ciò che richiede un paio di migliaia di cicli di clock o più prima che si sblocchi di nuovo (ad esempio compilando ed eseguendo un pezzo di javascript al volo) è male, esattamente per il motivo che hai dichiarato. Ma usare uno SpinLock per proteggere qualcosa che si completa rapidamente, come accedere a una mappa hash correttamente implementata, va bene perché il thread in attesa gira solo 2 o 3 volte e quindi non spreca risorse di sistema.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.