Synchronization of individual writes to shared memory (MPI)

To keep things simple and to focus on the core of my problem, let's assume that the memory location addressed locally by a pointer variable ptr

is shared across multiple processes. I in particular use MPI shared memory windows in C / ++ for memory allocation and sharing. To be specific, let's say it ptr

refers to a floating point variable, so locally we have

float* ptr;

      

Now suppose all processes are trying to write the same value const float f

to ptr, i.e.

*ptr = f;

      

My question is, does this operation require synchronization or can it be done at the same time, given the fact that all processes try to change bytes the same way, i.e. given the fact that it f

has the same value for each to process. So my question boils down to: for concurrent writes like floating point variables, is there a chance that a race condition results in an inconsistent byte pattern even though each process is trying to modify memory in the same way. That is, if I know for sure that each process writes the same data, can I omit synchronization?

+3


source to share


2 answers


Yes, you must sync the shared memory. the fact that the changing threads are in different processes is irrelevant, it is still a data race (writing to shared memory from different threads).

Note that there are other problems that deal with synchronization problems, such as visibility and memory reordering, what is written in shared memory does not matter.

the standard does not currently define the idea of ​​a process (thread only) and does not provide any means of synchronization between processes.



you are allocating std::mutex

in shared memory and using that as a synchronization primitive, or relying on synchronization primitives between multiple win32 processes such as a mutex, semaphore or event.

alternatively, if you only want to sync a primitive, you can allocate std::atomic<T>

in shared memory and use that as your synchronized primitive.

+1


source


In C ++, if multiple processes write to the same memory location without properly using synchronization primitives or atomic operations, undefined behavior occurs. (That is, it may work, it may not work, the computer may catch fire.)

In practice, on your computer, it is basically sure that it works the way you think it should work. It's actually plausible that things don't go as you expect on some architectures: if the CPU can't read / write a block of memory as small as your total value, or if the total value store crosses an alignment boundary, such a write could actually include and reading, and that read-modify-write can have the effect of reverting or garbling other changes in memory.

The easiest way to get what you want is to simply write it as a "relaxed" atomic operation:



std::atomic_store_explicit(ptr, f, std::memory_order_relaxed);

      

This ensures that the write is "atomic" in the sense of not respecting the race of the data and will not incur any overhead other than architectures where problems with *ptr = f

.

+1


source







All Articles