Shared memory and copy on write or rvalue references and move semantics?
Asked Answered
D

2

8

Is a shared memory/copy on write implementation for general containers (like that found in Qt's containers) superseded by C++11 move semantics and rvalue references?

Where does one fail and the other succeed? Or are they complementary rather than alternatives?

Dimarco answered 18/4, 2013 at 20:8 Comment(0)
T
7

Both copy on write and move semantics have been used to optimize value semantics of objects that hold their data on the heap. std::string, for example has been implemented both as a copy-on-write object, and as a move-enabled object.

So copy-on-write and move semantics is similar in that regard: they can both be used to optimize "copies" if you define "copy" loosely enough. I've sometimes described move semantics as copy-on-write with the reference count being limited to 0 or 1, and thus the field containing the reference count is optimized away.

All of the containers in the std::lib now use move semantics and even std::string, which used to be allowed to use copy-on-write, is now forbidden from doing so. If I were writing a new customer container today, I would use move semantics before choosing copy-on-write.

There is still a use for copy-on-write in C++11. If you expect your data structure to be rarely written to, but copied often, with many clients holding copies of the same value, copy-on-write can still be a large win.

For example I've seen copy-on-write put to good use to hold an undo-list for a complex document. At any given commit (where you want to save state), only a small piece of the large document has changed since the last commit. So making a copy of the document to save its state means updating a bunch of reference counts, and actually making changes (copy-on-write style) to a small piece.

Tessellation answered 18/4, 2013 at 21:52 Comment(1)
Would it be possible to stuff the copy-on-write semantics in e.g. an allocator? Of course by modifying the interface functions to actually use the allocator when necessary. I doubt std::allocator has the required interface though?Dimarco
M
6

Copy-on-write and move semantics are completely different concepts, each serving a different purpose. While there is a common use case: returning an object from a function, in which because the original goes out of scope it is effectively a move, in the general case they differ:

With copy on write multiple objects that are alive at the same time can share the content. With move semantics only one object has the contents in a particular point in time.

A bit orthogonal to this, copy-on-write has issues in multithreaded environments, since there are potentially multiple objects accessing the same data (read only) and control block (read/write), which needs to be managed in a thread safe manner.

Mutinous answered 18/4, 2013 at 20:16 Comment(1)
Currently I'm looking for a copy on write implementation of containers, because they are used in a multithreaded environment in order to avoid long locks. In my case I have a master container and several iterators that must be able to safely iterate over its content. Copy on write with atomic reference counting would do the job for me.Yacano

© 2022 - 2024 — McMap. All rights reserved.