sembra che parte quello che stai realmente chiedendo è:
Perché non è il prefisso di lock
implicito per cmpxchg
con un operando di memoria, like it is for xchg
?
La semplice risposta (che altri hanno dato) è semplicemente che Intel l'ha progettata in questo modo. Ma questo porta alla domanda:
Perché Intel l'ha fatto? Esiste un caso d'uso per cmpxchg
senza lock
?
In un sistema a CPU singola, cmpxchg
è atomico rispetto altri fili, o qualsiasi altro codice in esecuzione sullo stesso nucleo CPU. (Ma non per gli osservatori "di sistema" come un dispositivo I/O mappato in memoria, o un dispositivo che fa letture DMA di memoria normale, quindi lock cmpxchg
era rilevante anche su progetti CPU uniprocessore).
Gli interruttori di contesto possono verificarsi solo su interrupt e gli interrupt si verificano prima o dopo un'istruzione, non nel mezzo. Qualsiasi codice in esecuzione sulla stessa CPU vedrà lo cmpxchg
come completamente eseguito o non del tutto.
Ad esempio, il kernel di Linux è normalmente compilato con il supporto SMP, in modo che utilizza lock cmpxchg
per CAS atomica. Tuttavia, quando viene avviato su un sistema a processore singolo, verrà applicato il prefisso lock
a nop
ovunque il codice sia stato allineato, poiché nop
cmpxchg
viene eseguito molto più rapidamente di lock cmpxchg
. Per maggiori informazioni, vedi questo LWN article about Linux's "SMP alternatives" system. Può anche applicare patch ai prefissi lock
prima di collegare a caldo una seconda CPU.
Leggi di più riguardo atomicità delle singole istruzioni su sistemi monoprocessore in this answer, e in @supercat's answer + comments su Can num++
essere atomica per int num
. Vedere my answer there per molti dettagli su come l'atomicità funziona davvero/è implementata per le istruzioni di lettura-modifica-scrittura come lock cmpxchg
.
(Lo stesso ragionamento vale per cmpxchg8b
/cmpxchg16b
, e xadd
, che di solito utilizzato solo per synchonization/OPS atomici, non fare-single threaded conduzione codice più veloce. Ovviamente memoria destinazione add [mem], reg
è all'esterno utile il caso lock add [mem], reg
.)
Ovviamente è possibile utilizzare un indirizzo di memoria, questo è il punto. Il primo operando è di tipo r/m, quindi eccoti. E come potresti prefisso l'istruzione con 'lock' se non esistesse? – harold
@harold Non capisco cosa non esista. Si prefissa con LOCK se si desidera che l'istruzione sia atomica. Quindi CMPXCHG, senza prefisso LOCK, è atomico o no? –
No, ma nella tua domanda 2 ti sembra di chiedere perché "cmpxchg senza blocco" esista, che è un po 'strano, dato che la combinazione non può esistere senza le parti - se questo non è ciò che intendi, puoi chiarire? – harold