rwallace
rwallace

Reputation: 33395

Atomic write of nearby one-byte variables

Suppose, on a multiprocessor machine, there are two global variables A and B, each one byte in size, located near each other in memory, and two CPUs executing the following code.

CPU 1:

read A
calculate new value
write A

CPU 2:

read B
calculate new value
write B

Just looking at what would tend to physically happen, we would expect the above would be incorrect without any explicit locking because A and B could be in the same cache line, and CPU 1 needs to read the entire cache line, change the value of a single byte and write the line again; if CPU 2 does its read-modify-write of the cache line in between, the update to B could be lost. (I'm assuming it doesn't matter what order A and B are updated in, I'm only concerned with making sure neither update is lost.)

But x86 guarantees this code is okay. On x86, a write to a single variable only becomes non-atomic if that variable is misaligned or bigger than the CPU word size.

Does an x86 CPU automatically carry out extra locking on the front side bus in order to make such individual variable updates, work correctly without explicit locking?

Upvotes: 3

Views: 326

Answers (2)

LWimsey
LWimsey

Reputation: 6647

The code is correct because the standard provides the following guarantee (1.7.3):

Two or more threads of execution can access separate memory locations without interfering with each other.

It is possible that the variables share the same cache line. That may lead to false sharing, i.e. each core invalidates the cache line upon a write and other cores that access the same cache line will have to get their data from memory higher up in the chain.

That will slow things down, but from a correctness point of view, false sharing is irrelevant since separate memory locations can still be accessed without synchronization.

Upvotes: 1

Alexandr Konovalov
Alexandr Konovalov

Reputation: 578

This code is correct because of cache coherency protocol. When CPU1 modifies cache line, this line became Invalid in the cache of CPU 2, and CPU 2 can't write B and must wait (See https://en.wikipedia.org/wiki/MESIF_protocol for the state machine).

So no updates are lost, and no bus locks required.

Upvotes: 2

Related Questions