Essendo stato la lettura attraverso Understanding the Linux kernel (Bovet & Cesati),
il capitolo sul kernel di sincronizzazione afferma che il codice di acquisizione spin lock si riduce a:Gli spinlock di Linux/SMP sono inutilmente lenti?
1: lock:
btsl $0, slp
jnc 3
2: testb $1, slp
jne 2
jmp 1
3:
Ora ho inizialmente pensato che sembrava uno spreco avere cicli annidati e si potrebbe implementare qualcosa di simile :
1: lock:
btsl $0, slp
jc 1
che sarebbe molto più semplice. Tuttavia, vedo perché lo hanno fatto poiché lo lock
ha effetto sulle altre CPU e le tempificazioni per lo btsl
sono maggiori di quelle per un semplice testb
.
L'unica cosa che io non ho stato in grado di capirmi è la successiva versione dello spin lock. Il libro afferma che ottengono i seguenti:
lock:
btrl $0, slp
La mia domanda è fondamentalmente perché? Mi sembra che una combo lock/mov-immediate
sia più veloce.
Non è necessario riportare il vecchio stato al flag di trasporto poiché, seguendo la regola che il kernel è privo di errori (assunto in molti altri punti all'interno di detto kernel), il vecchio stato sarà 1 (tu non proverei a rilasciarlo se non lo avessi già acquisito).
E un mov
è molto più veloce di un btrl
, almeno sulla 386.
Allora, cosa mi manca?
I tempi sono cambiati per quelle istruzioni sui chip successivi?
Il kernel è stato aggiornato da quando è stato stampato il libro?
Il libro è semplicemente errato (o mostra istruzioni semplificate)?
Ho perso qualche altro aspetto che coinvolge la sincronizzazione tra le CPU che l'istruzione più veloce non soddisfa?