Why C++ has introduced separate std::latch and std::barrier? - c++

There are some similar questions on SO. But they only ask the question one way.
std::latch has an advantage over std::barrier that unlike latter, former can be decremented by a participating thread more than once.
std::barrier has an advantage over std::latch that unlike latter, former can be reused once the arriving threads are unblocked at a phase's synchronization point.
But my question is, why have two almost identical things in the first place? Why they decided not combine both of them into one, something like Java Phaser?
Phaser was introduced in Java7, as a more flexible option over CountDownLatch and CyclicBarrier, which were introduced in Java5. It has almost identical API as that of both former classes. (Here I took Java's example just to show that combining them is indeed possible.)
Instead of providing a single phaser class, they decided to separately provide latch and barrier, then there must be some benefit from having them separately, mostly some performance related issue. So, what is that issue precisely?

C++ has an principle of not paying for something that you don't use. If std::barrier can be implemented more efficient than std::latch for the case when you don't use it twice from the same thread - there is a reason to provide a more efficient idiom together with a more generic.
As for "what is that issue precisely": C++ has no virtual machine that equalizes all systems. Moreover, STL doesn't specify the exact implementation of the class. So the implementation of latch/barrier is the matter of a system, vendor or taste of the developer.

Related

Why doesn't C++ have a std::thread_pool in the standard library?

It just seems strange to me that despite having a very large set of constructs for multithreading, the standard lacks a thread pool class. What reasons might dissuade the committee from adding this to the standard?
C++, like C, is meant to give as much control to the programmer as possible. Almost everything in C++ is a wrapper that is very bare-bones. This give the programmer freedom to implement whatever feature they want however they want.
The concept of "what is work" is a bit abstract and dependent on the use case, so C++ gives you the workers (threads), and lets you define a strategy for how you want that work to be distributed amongst the workers.
For example, in Python, you can map work to threads. Using this means that whenever work is available, a thread will take the work. But what if you want a thread to only do work if there is work to do AND after certain conditions are met. You can design your thread_pool class to meet all these specifications. In Python, you'd have to handle these checks separately outside of the thread pooling library.
While there is no OFFICIAL answer, this is the answer that I would say makes more sense. C++ is about control given a minimal amount of tools (however an EXTENDED set compared to C). The committee is most likely not adding a thread_pool class because the hardest thing to do in Computer Science is getting people to agree. Thread pooling is not necessarily extremely hard to implement, and defining a definition of worker is arguably harder.

Force two threads to access a global variable directly in memory?

I know that volatile in C++ does not have the same meaning as in Java, so if I'm writing a C++ application for Windows, how can I share a variable between two threads and not allowing for each thread to cache its own copy of the variable?
Does using critical sections solves this problem or does it only allows for atomicity?
Actually, on Visual Studio, volatile does have pretty much the same meaning as in Java (or C#). Or at least, it used to, and still does by default; see Microsoft's documentation for details.
That said, in standard C++, it is true that volatile means approximately nothing. Also, in standard terms, threads do not "cache" anything and your question is ill-formed. The relevant concepts are atomicity and ordering, the standard term for the latter being the "happens-before" relationship. Everything you need to design, implement, and reason about multi-threaded algorithms is captured in these concepts; the notion of "cache" has nothing to do with it.
Standard C++11 provides many mechanisms for enforcing atomicity and ordering. You will get a better answer if you ask a specific question about implementing a specific algorithm.
[Update, to clarify]
Note that I am not saying you are using the wrong terminology; I am saying you are using the wrong concepts.
The standard does not talk about "cached variables" using different words... It does not talk about cached variables at all. That is because the concept is neither necessary nor sufficient for reasoning about threads. You can know everything about caches and still be unable to analyze concurrent algorithms, and you can know nothing about caches and be able to analyze them perfectly.
Similarly, "accessing a variable directly" is not just the wrong way to talk; the very concept is meaningless in (standard) C++. The notion of "do it right now" means nothing when each thread is progressing at a different rate and observing state changes in a different order. In standard C++, there simply is no "access directly" or "right now"; there is only happens-before.
This is not an academic point. The wrong mental model for concurrency is almost guaranteed to lead to fuzzy thinking and sloppy, buggy code.
Your question really does have no answer as phrased. The right answer could be to use std::atomic or to use std::mutex or to use std::atomic_thread_fence, depending on exactly what it is you are actually trying to do. I am suggesting you ask a question that states clearly what that is.

dispatch_async() from Grand Central Dispatch and std::async from C++11

I have got some experience using GCD for concurrency and removing explicit locks and threads.
C++11 provides std::async, which seems to provide some similar features(, I'm not a C++ expert, please don't blame me for mistakes on it).
Putting aside arguments on flavours and language preferences, is there any benchmark comparing the two for their performance, especially for platforms like iOS?
Is c++11's std::async worth trying from a practical perspective?
EDIT:
As stackmonster answered, C++11 does not provide something exactly like a dispatch queue per se. However, isn't it possible to make an ad-hoc serial queue with atomic data structures(, and arguable lambda functions) to achieve this?
C++ 11 std::async is not nearly as sophisticated as grand central dispatch.
Its more analogous to the async concurrency model provided by the java.util.concurrent package
providing templates for callbacks but with no built in performance advantages.
I would say that the difference between them is simply this.
A callback template has no particular performance characteristics. GCD is all about performance, and threading/multiplexing those callbacks to reduce thread creation overhead and allowing queuing and task dependencies and thread pooling.
The launch policies of std::async do not compare in their sophistication to GCD and are not implementation portable.
Im not really sure what a benchmark between the two would really prove since they are not that really similar.
As others have already pointed out, this comparison is generally meaningless due to its apples/oranges nature, though if you really wanted to I suppose you could test std::async and std::future against some GCD based futures implementation you cobble together yourself and see which provides futures the quickest for a known set of computations. Might be vaguely interesting, but you'd have to be the one to do it since the experiment is likely too strange and esoteric to be of interest to anyone else. :-)

Is the PIMPL idiom really used in practice?

I am reading the book "Exceptional C++" by Herb Sutter, and in that book I have learned about the PIMPL idiom. Basically, the idea is to create a structure for the private objects of a class and dynamically allocate them to decrease the compilation time (and also hide the private implementations in a better manner).
For example:
class X
{
private:
C c;
D d;
} ;
could be changed to:
class X
{
private:
struct XImpl;
XImpl* pImpl;
};
and, in the .cpp file, the definition:
struct X::XImpl
{
C c;
D d;
};
This seems pretty interesting, but I have never seen this kind of approach before, neither in the companies I have worked, nor in open source projects that I've seen the source code. So, I am wondering whether this technique is really used in practice.
Should I use it everywhere, or with caution? And is this technique recommended to be used in embedded systems (where the performance is very important)?
So, I am wondering it this technique is really used in practice? Should I use it everywhere, or with caution?
Of course it is used. I use it in my project, in almost every class.
Reasons for using the PIMPL idiom:
Binary compatibility
When you're developing a library, you can add/modify fields to XImpl without breaking the binary compatibility with your client (which would mean crashes!). Since the binary layout of X class doesn't change when you add new fields to Ximpl class, it is safe to add new functionality to the library in minor versions updates.
Of course, you can also add new public/private non-virtual methods to X/XImpl without breaking the binary compatibility, but that's on par with the standard header/implementation technique.
Data hiding
If you're developing a library, especially a proprietary one, it might be desirable not to disclose what other libraries / implementation techniques were used to implement the public interface of your library. Either because of Intellectual Property issues, or because you believe that users might be tempted to take dangerous assumptions about the implementation or just break the encapsulation by using terrible casting tricks. PIMPL solves/mitigates that.
Compilation time
Compilation time is decreased, since only the source (implementation) file of X needs to be rebuilt when you add/remove fields and/or methods to the XImpl class (which maps to adding private fields/methods in the standard technique). In practice, it's a common operation.
With the standard header/implementation technique (without PIMPL), when you add a new field to X, every client that ever allocates X (either on stack, or on heap) needs to be recompiled, because it must adjust the size of the allocation. Well, every client that doesn't ever allocate X also need to be recompiled, but it's just overhead (the resulting code on the client side will be the same).
What is more, with the standard header/implementation separation XClient1.cpp needs to be recompiled even when a private method X::foo() was added to X and X.h changed, even though XClient1.cpp can't possibly call this method for encapsulation reasons! Like above, it's pure overhead and is related with how real-life C++ build systems work.
Of course, recompilation is not needed when you just modify the implementation of the methods (because you don't touch the header), but that's on par with the standard header/implementation technique.
Is this technique recommended to be used in embedded systems (where the performance is very important)?
That depends on how powerful your target is. However the only answer to this question is: measure and evaluate what you gain and lose. Also, take into consideration that if you're not publishing a library meant to be used in embedded systems by your clients, only the compilation time advantage applies!
It seems that a lot of libraries out there use it to stay stable in their API, at least for some versions.
But as for all things, you should never use anything everywhere without caution. Always think before using it. Evaluate what advantages it gives you, and if they are worth the price you pay.
The advantages it may give you are:
helps in keeping binary compatibility of shared libraries
hiding certain internal details
decreasing recompilation cycles
Those may or may not be real advantages to you. Like for me, I don't care about a few minutes recompilation time. End users usually also don't, as they always compile it once and from the beginning.
Possible disadvantages are (also here, depending on the implementation and whether they are real disadvantages for you):
Increase in memory usage due to more allocations than with the naïve variant
increased maintenance effort (you have to write at least the forwarding functions)
performance loss (the compiler may not be able to inline stuff as it is with a naïve implementation of your class)
So carefully give everything a value, and evaluate it for yourself. For me, it almost always turns out that using the PIMPL idiom is not worth the effort. There is only one case where I personally use it (or at least something similar):
My C++ wrapper for the Linux stat call. Here the struct from the C header may be different, depending on what #defines are set. And since my wrapper header can't control all of them, I only #include <sys/stat.h> in my .cxx file and avoid these problems.
I agree with all the others about the goods, but let me put in evidence about a limit: doesn't work well with templates.
The reason is that template instantiation requires the full declaration available where the instantiation took place. (And that's the main reason you don't see template methods defined into .cpp files.)
You can still refer to templatised subclasses, but since you have to include them all, every advantage of "implementation decoupling" on compiling (avoiding to include all platform-specific code everywhere, shortening compilation) is lost.
It is a good paradigm for classic OOP (inheritance based), but not for generic programming (specialization based).
Other people have already provided the technical up/downsides, but I think the following is worth noting:
First and foremost, don't be dogmatic. If PIMPL works for your situation, use it - don't use it just because "it's better OO since it really hides implementation", etc. Quoting the C++ FAQ:
encapsulation is for code, not people (source)
Just to give you an example of open source software where it is used and why: OpenThreads, the threading library used by the OpenSceneGraph. The main idea is to remove from the header (e.g., <Thread.h>) all platform-specific code, because internal state variables (e.g., thread handles) differ from platform to platform. This way one can compile code against your library without any knowledge of the other platforms' idiosyncrasies, because everything is hidden.
I would mainly consider PIMPL for classes exposed to be used as an API by other modules. This has many benefits, as it makes recompilation of the changes made in the PIMPL implementation does not affect the rest of the project. Also, for API classes they promote a binary compatibility (changes in a module implementation do not affect clients of those modules, they don't have to be recompiled as the new implementation has the same binary interface - the interface exposed by the PIMPL).
As for using PIMPL for every class, I would consider caution because all those benefits come at a cost: an extra level of indirection is required in order to access the implementation methods.
I think this is one of the most fundamental tools for decoupling.
I was using PIMPL (and many other idioms from Exceptional C++) on embedded project (SetTopBox).
The particular purpose of this idiom in our project was to hide the types XImpl class uses.
Specifically, we used it to hide details of implementations for different hardware, where different headers would be pulled in. We had different implementations of XImpl classes for one platform and different for the other. Layout of class X stayed the same regardless of the platform.
I used to use this technique a lot in the past but then found myself moving away from it.
Of course it is a good idea to hide the implementation detail away from the users of your class. However you can also do that by getting users of the class to use an abstract interface and for the implementation detail to be the concrete class.
The advantages of pImpl are:
Assuming there is just one implementation of this interface, it is clearer by not using abstract class / concrete implementation
If you have a suite of classes (a module) such that several classes access the same "impl" but users of the module will only use the "exposed" classes.
No v-table if this is assumed to be a bad thing.
The disadvantages I found of pImpl (where abstract interface works better)
Whilst you may have only one "production" implementation, by using an abstract interface you can also create a "mock" inmplementation that works in unit testing.
(The biggest issue). Before the days of unique_ptr and moving you had restricted choices as to how to store the pImpl. A raw pointer and you had issues about your class being non-copyable. An old auto_ptr wouldn't work with forwardly declared class (not on all compilers anyway). So people started using shared_ptr which was nice in making your class copyable but of course both copies had the same underlying shared_ptr which you might not expect (modify one and both are modified). So the solution was often to use raw pointer for the inner one and make the class non-copyable and return a shared_ptr to that instead. So two calls to new. (Actually 3 given old shared_ptr gave you a second one).
Technically not really const-correct as the constness isn't propagated through to a member pointer.
In general I have therefore moved away in the years from pImpl and into abstract interface usage instead (and factory methods to create instances).
As many other said, the Pimpl idiom allows to reach complete information hiding and compilation independency, unfortunately with the cost of performance loss (additional pointer indirection) and additional memory need (the member pointer itself). The additional cost can be critical in embedded software development, in particular in those scenarios where memory must be economized as much as possible.
Using C++ abstract classes as interfaces would lead to the same benefits at the same cost.
This shows actually a big deficiency of C++ where, without recurring to C-like interfaces (global methods with an opaque pointer as parameter), it is not possible to have true information hiding and compilation independency without additional resource drawbacks: this is mainly because the declaration of a class, which must be included by its users, exports not only the interface of the class (public methods) needed by the users, but also its internals (private members), not needed by the users.
Here is an actual scenario I encountered, where this idiom helped a great deal. I recently decided to support DirectX 11, as well as my existing DirectX 9 support, in a game engine.
The engine already wrapped most DX features, so none of the DX interfaces were used directly; they were just defined in the headers as private members. The engine uses DLL files as extensions, adding keyboard, mouse, joystick, and scripting support, as week as many other extensions. While most of those DLLs did not use DX directly, they required knowledge and linkage to DX simply because they pulled in headers that exposed DX.
In adding DX 11, this complexity was to increase dramatically, however unnecessarily. Moving the DX members into a PIMPL, defined only in the source, eliminated this imposition.
On top of this reduction of library dependencies, my exposed interfaces became cleaner as I moved private member functions into the PIMPL, exposing only front facing interfaces.
One benefit I can see is that it allows the programmer to implement certain operations in a fairly fast manner:
X( X && move_semantics_are_cool ) : pImpl(NULL) {
this->swap(move_semantics_are_cool);
}
X& swap( X& rhs ) {
std::swap( pImpl, rhs.pImpl );
return *this;
}
X& operator=( X && move_semantics_are_cool ) {
return this->swap(move_semantics_are_cool);
}
X& operator=( const X& rhs ) {
X temporary_copy(rhs);
return this->swap(temporary_copy);
}
PS: I hope I'm not misunderstanding move semantics.
It is used in practice in a lot of projects. It's usefulness depends heavily on the kind of project. One of the more prominent projects using this is Qt, where the basic idea is to hide implementation or platform-specific code from the user (other developers using Qt).
This is a noble idea, but there is a real drawback to this: debugging
As long as the code hidden in private implementations is of premium quality this is all well, but if there are bugs in there, then the user/developer has a problem, because it just a dumb pointer to a hidden implementation, even if he/she has the implementations source code.
So as in nearly all design decisions there are pros and cons.
I thought I would add an answer because although some authors hinted at this, I didn't think the point was made clear enough.
The primary purpose of PIMPL is to solve the N*M problem. This problem may have other names in other literature, however a brief summary is this.
You have some kind of inhertiance hierachy where if you were to add a new subclass to your hierachy, it would require you to implement N or M new methods.
This is only an approximate hand-wavey explanation, because I only recently became aware of this and so I am by my own admission not yet an expert on this.
Discussion of existing points made
However I came across this question, and similar questions a number of years ago, and I was confused by the typical answers which are given. (Presumably I first learned about PIMPL some years ago and found this question and others similar to it.)
Enables binary compatiability (when writing libraries)
Reduces compile time
Hides data
Taking into account the above "advantages", none of them are a particularly compelling reason to use PIMPL, in my opinion. Hence I have never used it, and my program designs suffered as a consequence because I discarded the utility of PIMPL and what it can really be used to accomplish.
Allow me to comment on each to explain:
1.
Binary compatiability is only of relevance when writing libraries. If you are compiling a final executable program, then this is of no relevance, unless you are using someone elses (binary) libraries. (In other words, you do not have the original source code.)
This means this advantage is of limited scope and utility. It is only of interest to people who write libraries which are shipped in proprietary form.
2.
I don't personally consider this to be of any relevance in the modern day when it is rare to be working on projects where the compile time is of critical importance. Maybe this is important to the developers of Google Chrome. The associated disadvantages which probably increase development time significantly probably more than offset this advantage. I might be wrong about this but I find it unlikely, especially given the speed of modern compilers and computers.
3.
I don't immediatly see the advantage that PIMPL brings here. The same result can be accomplished by shipping a header file and a binary object file. Without a concrete example in front of me it is difficult to see why PIMPL is relevant here. The relevant "thing" is shipping binary object files, rather than original source code.
What PIMPL actually does:
You will have to forgive my slightly hand-wavey answer. While I am not a complete expert in this particular area of software design, I can at least tell you something about it. This information is mostly repeated from Design Patterns. The authors call it "Bridge Pattern" aka Handle aka Body.
In this book, the example of writing a Window manager is given. The key point here is that a window manager can implement different types of windows as well as different types of platform.
For example, one may have a
Window
Icon window
Fullscreen window with 3d acceleration
Some other fancy window
These are types of windows which can be rendered
as well as
Microsoft Windows implementation
OS X platform implementation
Linux X Window Manger
Linux Wayland
These are different types of rendering engines, with different OS calls and possibly fundamentally different functionality as well
The list above is analagous to that given in another answer where another user described writing software which should work with different kinds of hardware for something like a DVD player. (I forget exactly what the example was.)
I give slightly different examples here compared to what is written in the Design Patterns book.
The point being that there are two seperate types of things which should be implemented using an inheritance hierachy, however using a single inheritance hierachy does not suffice here. (N*M problem, the complexity scales like the square of the number of things in each bullet point list, which is not feasible for a developer to implement.)
Hence, using PIMPL, one seperates out the types of windows and provides a pointer to an instance of an implementation class.
So PIMPL:
Solves the N*M problem
Decouples two fundamentally different things which are being modelled using inheritance such that there are 2 or more hierachies, rather than just one monolith
Permits runtime exchange of the exact implementation behaviour (by changing a pointer). This may be advantagous in some situations, whereas a single monolith enforces static (compile time) behaviour selection rather than runtime behaviour selection
There may be other ways to implement this, for example with multiple inheritance, but this is usually a more complicated and difficult approach, at least in my experience.

Fast dynamic casting progress

A little while ago, I found that very interesting paper on a very neat performance upgrade for dynamic_cast in C++: http://www2.research.att.com/~bs/fast_dynamic_casting.pdf.
Basically, it makes dynamic_cast in C++ way faster than the traditional research in inheritance tree. As stated in the paper, the method provides for a fast, constant-time dynamic casting algorithm.
This paper was published in 2005. Now, I am wondering if the technique was ever implemented somewhere or if there are plans to implement it anywhere?
I do not know what implementations various compilers use beside GCC (which isn't linear). However, it is important to stress that the paper does not necessarily propose a method that is always faster than existing implementations for all (or even common) usage. It proposes a general solution that is asymptotically better as inheritance hierarchies grow.
However, it is rarely a good design to have large inheritance hierarchies, as they tend to force the application to become monolithic and inflexible to change. Programs with flexible design tend to only have hierarchies mostly with 2 levels, an abstract base and an implementation of runtime polymorphic roles to support the Open/Closed Principle. In these cases, walking the inheritance graph can be as simple as a single pointer dereference and compare, which can be faster than the index-sum-then-dereference-then-compare presented by Gibbs and Stroustrup.
Also, it is important to stress that it is never necessary to write a program that uses dynamic_cast unless your own business rules require it. The use of dynamic_cast is always an indication that polymorphism is not being properly used and reuse is being compromised. If you need a behavior based on casting up a hierarchy, adding a virtual method gives the clean solution. If you have a code section that does dynamic_cast-checks on types, that section of code will never "close" (in the meaning of the Open/Closed Principle), and will need to be updated for every new type added to the system. A virtual dispatch, on the other hand, is added only on new types, allowing you to remain open to expansion and yet closing the behaviors operating on the base type.
So this is really a rather academic suggestion (equating to changing a map to a hash_map algorithmically) that shouldn't have real world effects if good design is followed. If business rules forbid good design (some shops may have code barriers or code ownership issues where you cannot change existing architectures the way they need to be, nor do they allow adaptors to be built as would commonly be used for 3rd party libraries), then it is best not to make the decision on which compiler to use based on what algorithm is implemented. As always, if performance is key and you have to use a feature like dynamic_cast, profile your code. It is possible (and likely in many cases) that the tree-walking implementation is faster in practice.
See also the standards committee's review of implementations, including dynamic_cast and a well-known look at c++ in embedded environments and good use (which mentions Gibbs and Stroustrup in passing).