Wydaje się, że część tego, czego naprawdę pytaniem jest:
Dlaczego nie jest lock
prefiks niejawny dla cmpxchg
z argumentu pamięci, like it is for xchg
?
Prostą odpowiedzią (którą dali inni) jest to, że Intel zaprojektował ją w ten sposób. Ale to prowadzi do pytania:
Dlaczego Intel to zrobił? Czy istnieje przypadek użycia dla cmpxchg
bez lock
?
W systemie pojedynczego procesora, cmpxchg
jest atomowej w odniesieniu do innych wątków, lub jakikolwiek inny kod uruchomiony na tym samym rdzeniu procesora. (Ale nie dla "systemowych" obserwatorów, takich jak odwzorowane w pamięci urządzenia I/O, czy też urządzenia robiące DMA czyta normalną pamięć, więc lock cmpxchg
było istotne nawet w projektach jednoprocesorowych CPU).
Przełączniki kontekstu mogą się zdarzyć tylko w przypadku przerwania, a przerywanie następuje przed lub po instrukcji, a nie w środku. Każdy kod działający na tym samym procesorze będzie oznaczał, że cmpxchg
jest w pełni wykonany lub wcale nie jest.
Na przykład jądro Linux jest zwykle skompilowany z obsługą SMP, więc używa lock cmpxchg
dla atomowej CAS. Ale po uruchomieniu w systemie z jednym procesorem, będzie łatał prefiks lock
do nop
wszędzie tam, gdzie kod był wstawiony, ponieważ nop
cmpxchg
działa znacznie szybciej niż lock cmpxchg
. Aby uzyskać więcej informacji, zobacz: LWN article about Linux's "SMP alternatives" system. Może nawet przywrócić do prefiksów lock
przed podłączeniem na gorąco drugiego procesora.
Więcej o atomowości pojedynczych instrukcji w systemach jedno- in this answer, aw @supercat's answer + comments ON może być num++
atomowy dla int num
. Zobacz my answer there, aby uzyskać wiele szczegółowych informacji o tym, jak atomowość naprawdę działa/jest zaimplementowana w instrukcjach read-modify-write, takich jak lock cmpxchg
.
(To samo rozumowanie dotyczy również cmpxchg8b
/cmpxchg16b
i xadd
, które zwykle wykorzystywane wyłącznie do synchonization/ops atomowych, aby nie zrobić jednowątkowy uruchomić kod szybciej. Oczywiście pamięci przeznaczenia add [mem], reg
jest przydatna poza obudowa lock add [mem], reg
.)
Oczywiście można użyć adresu pamięci, to wszystko. Pierwszy operand jest typu r/m, więc masz. I jak możesz przedłużyć instrukcję 'lock', jeśli sama nie istnieje? – harold
@harold Nie bardzo rozumiem, co nie istnieje. Przedrostek z LOCK, jeśli chcesz, aby instrukcja była atomowa. Czy CMPXCHG, bez prefiksu LOCK, jest atomowe, czy nie? –
Nie, ale w pytaniu 2 zdaje się pan pytać, dlaczego istnieje "cmpxchg bez zamka", co jest dziwne, skoro kombinacja nie może istnieć bez części - jeśli nie to miałeś na myśli, to czy możesz to wyjaśnić? – harold