= Solution
With O1, even readers must acquire and release the same <mutex>. Acquiring it normally uses an <atomic read-modify-write> on the lock's <cache line>; releasing writes that <cache line> again. As different <CPU cores> repeatedly read the data, ownership of the lock's <cache line> moves among them, causing <cache coherence> traffic and serializing the protected operations. If the lock shares a <cache line> with otherwise stable data, <false sharing> can also invalidate useful reader data. The actual data need not change for this lock traffic to occur.
With O2 and correctly ordered publication, readers perform only <load instructions>: copy `p` once into a <processor register>, then read that version of the data. Multiple <CPU cores> can keep read-only shared copies of its <cache lines>. No per-reader exclusive ownership transfer is needed. During an update, a writer fills newly allocated <computer memory> privately; the old version's <cache lines> remain unchanged for readers already using it. Publishing the new <pointer> writes `p` and invalidates cached copies of that pointer's <cache line>, but this occurs only on updates.
\b[For many reads and rare updates, O2 avoids lock-line contention and permits concurrent readers, so it can be substantially faster.] The costs are <heap allocation>, construction or copying of a whole replacement, first accesses to its newly populated <cache lines>, and deferred <memory reclamation>. Frequent updates or very large replacements can reverse the comparison. O1 can modify a small field in place and may then save copying and <computer memory>. These are workload-dependent comparisons, not a claim that removing every <mutex> always accelerates an operation.
$$
\boxed{\text{Read-mostly immutable versions avoid per-reader lock-line writes.}}
$$
Back to article page