3

Are there any examples of the absence or presence of const affecting the concurrency of any C++ Standard Library algorithms or containers? If there aren't, is there any reason using the const-ness in this way is not permitted?

To clarify, I'm assuming concurrent const access to objects is data-race free, as advocated in several places, including GotW 6.

By analogy, the noexcept-ness of move operations can affect the performance of std::vectors methods such as resize.

I skimmed through several of the C++17 concurrent Algorithms, hoping to find an example, but I didn't find anything. Algorithms like transform don't require the unary_op or binary_op function objects to be const. I did find for_each takes a MoveConstructible function object for the original, non execution policy version, and take a CopyConstructible function object for the C++17 execution policy version; I thought this might be an example where the programmer was manually forced to select one or the other based on if the function object could be safely copied (a const operation)... but at the moment I suspect this requirement is just there to support the return type (UnaryFunction vs. void).

Charles L Wilcox
  • 1,126
  • 8
  • 18
  • Concurrent read-only acces to objects are always race-free regardless of `const` or not. – super Sep 29 '20 at 18:31
  • @super Calls to non-const `F::operator()` may not be data race free. – Charles L Wilcox Sep 29 '20 at 18:34
  • Your point being? Calls to const `F::operator()` can also contain data races. A `const` method is allowed to modify `mutable` members of the class. Those facts doesn't change the fact that read-only access is always race free. – super Sep 29 '20 at 18:38
  • @super As stated in GotW6: "Concurrent `const` operations on the same object are required to be safe without the calling code doing external synchronization." It goes on to address `mutable` state, sometimes for caching results, and always for multi-thread safe synchronization primitives (`atomic`, `mutable`). – Charles L Wilcox Sep 29 '20 at 18:50
  • Your point still remains a mystery. Good luck with your question. – super Sep 29 '20 at 18:53
  • @super Imagine a parallel `for_each` algorithm that: if `F::operator() const` is available it uses the input `f` object concurrently in each thread, else it makes a copy of `f` for each thread so that it can safely call `F::operator() /*non-const*/`. This would save copy constructor calls. (Of course, this isn't the only performance factor in this scenario: sharing one instance between threads may introduce some contention, for example.) – Charles L Wilcox Sep 29 '20 at 19:45
  • 1
    Related video: [H.Sutter. You don’t know `const` and `mutable`](https://channel9.msdn.com/posts/C-and-Beyond-2012-Herb-Sutter-You-dont-know-blank-and-blank) – Evg Sep 29 '20 at 20:03

0 Answers0