Jolle
Jolle

Reputation: 1416

Using Mutex for shared memory of 1 word

I have an application where multiple threads access and write to a shared memory of 1 word (16bit).

Can I expect that the processor reads and writes a word from/to memory in an atomic operation? So I don't need mutex protection of the shared memory/variable?

The target is an embedded device running VxWorks.

EDIT: There's only one CPU and it is an old one (>7years) - I am not exactly sure about the architecture and model, but I am also more interested in the general way that "most" CPU's will work. If it is a 16bit CPU, would it then, in most cases, be fair to expect that it will read/write a 16bit variable in one operation? Or should I always in any case use mutex protection? And let's say that I don't care about portability, and we talk about C++98.

Upvotes: 1

Views: 436

Answers (4)

Tony Delroy
Tony Delroy

Reputation: 106076

Can I expect that the processor reads and writes a word from/to memory in an atomic operation?

Yes, if the data's properly aligned and no bigger than a machine word, most CPU instructions will operate on it atomically in the sense you describe.

So I don't need mutex protection of the shared memory/variable?

You do need some synchronisation - whether a mutex or using atomic operations ala std::atomic.

The reasons for this include:

  • if your variable is not volatile, the compiler might not even emit read and write instructions for the memory address nominally holding that variable at the places you might expect, instead reusing values read or set earlier that are saved in CPU registers or known at compile time

    • if you use a mutex or std::atomic type you do not need to use volatile as well
  • further, even if the data is written towards memory, it may not leave the CPU caches and be written to actual RAM where other cores and CPUs can see it unless you explicitly use a memory barrier (std::mutex and std::atomic types do that for you)

  • finally, delays between reading and writing values can cause unexpected results, so operations like ++x can fail as explained by David Schwartz.

Upvotes: 1

David Schwartz
David Schwartz

Reputation: 182753

Can I expect that the processor reads and writes a word from/to memory in an atomic operation?

Yes.

So I don't need mutex protection of the shared memory/variable?

No. Consider:

++i;

Even if the read and write are atomic, two threads doing this at the same time can each read, each increment, and then each write, resulting in only one increment where two are needed.

Upvotes: 2

MikeMB
MikeMB

Reputation: 21136

The problem is not the atomicity of the acess (which you can usually assume unless you are using a 8bit MC), but the missing synchronization which leads to undefined behavior. If you want to write portable code, use atomics instead. If you want to achieve maximal performance for your specific platform, read the documentation of your OS and compiler very carefully and see what additional mechanisms or guarantees they provide for multithreaded programs (But I really doubt that you will find anything more efficient than std::atomic that gives you sufficient guarantees).

Upvotes: 2

Mats Petersson
Mats Petersson

Reputation: 129324

All processors will read and write aligned machine-words atomicially in the sense that you won't get half the bits of the old value and half the bits of the new value if read by another processor.

To achieve good speed, modern processors will NOT synchronize read-modif-write operations to a particular location unless you actually ask for it - since nearly all reads and writes go to "non-shared" locations.

So, if the value is, say, a counter of how many times we've encountered a particular condition, or some other "if we read/write an old value, it'll go wrong" situation, then you need to ensure that two processors don't simultaneously update the value. This can typically be done with atomic instructions (or some other form of atomic updates) - this will ensure that one, and only one, processor touches the value at any given time, and that all the other processors DO NOT hold a copy of the value that they think is accurate and up to date when another has just made an update. See the C++11 std::atomic set of functions.

Note the distinction between atomically reading or writing the machine word's value and atomically performing the whole update.

Upvotes: 2

Related Questions