magu_ magu_ - 3 months ago 15
C++ Question

Is a write to variable on a single core CPU atomic?

I have a single core CPU (ARM Cortex M3, 32bit) with two threads. Assuming the following situation:

// Thread 1:
int16_t a = 1;
double b = 1.0;
// Do some other fancy stuff including starting Thread 2
for (;;) {std::cout << a << "," <<b;}

// Thread 2:
a = 2;
b = 2.0;


I can handle the following outputs:


  • 1,1

  • 1,2

  • 2,1

  • 2,2



Can I be certain that the output will always be one of those (1/2) without using
mutex
or other locking mechanisms? And more specifically, is this compiler dependent? And is the behavior different for
int16
and
double
?

Answer

It depends on the CPU, mostly, though in theory anything involving multiple threads on pre-C11 is at best implementation defined and at worst undefined behavior, so the compiler might do just about anything.

If you can ignore crazy compilers that do silly things, and assume that the compiler will use the CPU's facilities in a reasonable way, it depends mostly on what the CPU supports.

Cortex-M3 is a 32-bit CPU with a 32-bit bus and no FPU. So reads and writes of 32-bit and smaller values will generally be atomic. double, however, is 64 bits, so any read/write of a double will involve two instructions and be non-atomic. Thus if one thread reads while the other is writing you might get half from one value and half from the other.

Now in your specific example, the values 1.0 and 2.0 are both 0 for their lower half, so the 'mix' would be innocuous, but other values will not have that behavior.