Are C ++ 11 objects potentially slower in multi-threaded environments due to the new const?

According to Herb Sutter ( http://isocpp.org/blog/2012/12/you-dont-know-const-and-mutable-herb-sutter ), in C ++ 11, const methods should not change the object bit by bit or must perform internal synchronization (for example, using a mutex) if they have mutable data elements.

Suppose I have a global object that I access from multiple threads, and suppose it has mutable members. For the argument, suppose we cannot change the source of the class (it is provided by a third-party).

In C ++ 98, these threads will use the global mutex to synchronize access to this object. Thus, access will require one lock / unlock mutex.

However, in C ++ 11, any call to a constant member function on this object will also cause internal synchronization, so potentially one call to the const const function on this object will cost 2 lock / unlock operations (or more, depending on how many functions you call from single thread). Note that a global mutex is still necessary because const does nothing for writers (except possibly slowing them down if one of the non-constant methods calls the const method).

So my question is: if all our classes should be this way in C ++ (at least for using STL), does this lead to excessive synchronization measures?

thanks

Edit: Some clarifications:

  • It seems that in C ++ 11 you cannot use a class with a standard library if its member functions are not internally synchronized (or do not perform any write operations).

  • While C ++ 11 does not automatically add any synchronization code, the standard compatible with the standard library does not require synchronization in C ++ 98, but it does need C ++ 11. Thus, in C ++ 98 you can do without internal synchronization for mutable members, but in C ++ 11 you cannot.

+4
source share
2 answers

Yes, you are absolutely right. You should make your objects the following recommendations, and therefore access to them will be potentially slower in C ++ 11. If and only if :

  • The class has mutable members whose members change const .

  • An object is drawn from multiple threads.

If you make sure that at least one of them is incorrect, nothing changes. The number of objects that are accessed from multiple threads should always be minimal. And the number of classes that have mutable members should be minimal. So, you are talking about a minimal set of a minimum set of objects.

And even then ... all that is required is that the data schedules will not be broken. Depending on what kind of data can be changed, it may just be atomic access.

I do not see a problem here. Few of the standard library objects will have mutable members. I offer you a reasonable implementation of basic_string , vector , map , etc., which need mutable elements.

It seems that in C ++ 11 you cannot use a class with a standard library if its member functions are not synchronized (or do not perform any write operations).

This is not true. You certainly can. What you cannot do is try to access this class from multiple threads in such a way as to "execute any records" on these mutable elements. If you never access this object through this C ++ 11 class in threads in a certain way, you're fine.

So yes, you can use them. But you only get the guarantees provided by your own class. If you use your class through a standard library class in an unreasonable way (for example, your const functions are not const or are correctly synchronized), then this is your mistake, not the library.

So, in C ++ 98 you can do without internal synchronization for mutable members, but in C ++ 11 you cannot.

It's like saying that you can get away with computer crime back in the Roman Empire. Of course you can. Then they did not have computers; therefore, they did not know what computer crime was.

In C ++ 98/03 there was no concept of "threads". Thus, the standard does not have the concept of "internal synchronization", so that you could or could not "leave with" was not defined nor undefined. It made no sense to ask a question about the standard, rather than asking what the hacking laws were during Caesir Day.

Now that C ++ 11 really defines this concept and idea of โ€‹โ€‹race status, C ++ 11 can tell when you can "get away from internal synchronization."

Or, to put it another way, this is how the two standards answer your question: what is the result of a potential data race in the mutable element when accessed through a member function declared by const in the standard library

C ++ 11: when accessing the const function there will be no data racing on any internal elements. All standard library implementations of such functions must be implemented in such a way that data race cannot occur.

C ++ 98/03: What data race?

+6
source

in C ++ 11, any call to the const member function on this object will also cause internal synchronization

Why? This synchronization does not just magically appear in the class, it is only there if someone explicitly adds it.

so potentially one call of the const const function on this object will cost 2 lock / unlock operations

Only if someone added an internal mutex to it and you also use an external ... but why would you do that?

Note that a global mutex is still necessary, because const does not seem to do anything for writers (with the possible exception of slowing them down if one of the non-const methods calls the const method).

If the class has an internal mutex used to create const threads, then it can also be used for const members. If the class does not have an internal mutex, then the situation is identical to the C ++ 98 situation.

I think you see a problem that does not exist.

Herb "the new meaning for const" is not used by the language or the compiler, it is just a design guide, that is, an idiom for good code. To follow this guide, you do not add mutexes to each class, so const members are allowed to modify mutable members, you avoid mutable members! . In rare cases, when you absolutely must have mutable members, either require users to do their own locking (and clearly document the class as requiring external synchronization), or add internal synchronization and pay extra cost ... but these situations should be rare, therefore, itโ€™s not true that โ€œC ++ 11 objects are slower due to the new const,โ€ because most well-designed objects do not have mutable elements.

+10
source

Source: https://habr.com/ru/post/1485115/


All Articles