Meeting C ++, Dusseldorf
It turned out that I was able to take part in the
conference dedicated to C ++. The level, of course, is not GoingNative: the reports were of different levels. Both very strong and interesting, and completely empty. The most important thing for me was the atmosphere - for a long time I personally did not discuss so many interesting topics with anyone. I liked it so much that I had the idea of ​​creating a C ++ User Group in St. Petersburg in order to communicate more personally with colleagues in the workshop. But more about that later, but for now about the conference. I will not describe and retell all the reports; I will only note the most interesting topics and topics that were touched on in almost every report.
Key Trends
- move semantics;
- asynchrony;
- network
- yin and yang productivity increase
- scaling c ++ applications on a multi-core architecture;
- c ++ on embedded systems.
Move semantics
By itself, move-semantics, I think, is familiar to everyone. A quick search gives several posts on Habré (
1 ,
2 ,
3 ). Almost every speaker squeezed something out of her. Of the interesting things, Eric Nibler speculated on how best to pass parameters to functions and what to return from them. Taking into account the sink-arguments and the fact that the compiler can recognize the rvalue, it turned out a great summary table
1 .
Category | Recommendations for C ++ 11 |
---|
Input Parameters : small and sink values other | Pass by value const ref |
Return value | Pass by value |
Input / Output Parameters | We use stateful algorithm object 2 |
Asynchrony
In addition to common words, such as “asynchrony begins with design”, complaints were mainly heard: after all, there is still no asynchronous I / O in the language. It is clear that an asynchronous program loses all meaning at synchronous input / output. Therefore, there was talk of future standards, of std :: async and std :: future, but, unfortunately, asynchrony in C ++ is more likely dead than alive. You can use many different good libraries or platform-specific solutions, but the language as it stood in this place is worth it.
According to the statements, the universal asynchronous model will be included only in C ++ 17. While you can get acquainted with its description
here .
What exactly can we use while waiting for this paradise on earth? Nothing new!
- POSIX: aio;
- FreeBSD: kqueue;
- Linux: epoll;
- anywhere boost :: asio.
Network
Everything is also as sad as asynchronous (if not worse). A representative of
WG21 / SG4 (research group on the network standardization committee) led their roadmap for the coming years:
- 2014 — network byte order, URI, IP address;
- 201X - Universal Asynchronous Model (the same), HTTP, Resolvers;
- 201Y - sockets, asynchronous input / output streams;
- 201Z - SSL, ICMP.
Personally, I am very depressed that HTTP will appear in the standard earlier than sockets. If I understand correctly, this is due to the fact that the demand for HTTP is much higher.
Productivity increase
As soon as we talk about improving performance, voices immediately burst into the conversation: “How can I correctly scale an application into several cores?” And “How can I optimize an application under embedded?”. If you think that C ++ and embedded are nonsense, here is a list of documents for your reference:
- Joint Strike Fighter Air Vehicle C ++ Coding Standards, Lockheed Martin Corporation, 2005;
- MISRA-C: 2008 - Guidelines for the C ++ language in critical systems, MIRA Limited, 2008;
- Technical Report on C ++ Performance , Chapter 7, Using C ++ in Embedded Systems.
In the aspect of C ++ 11, both problems can be considered from a common point of view.
- Our favorite asynchrony: gives us a lock- and wait-free on multi-core architectures, moving away from a large number of threads in embedded.
- Where it is possible to use PODs, since now there is is_pod, is_trivial, is_standard_layout allowing the standard library (yes, and us) to figure out where to copy memory in blocks, and where it is necessary to do element-wise copying.
- Nowhere without move semantics. We save on unnecessary movements.
- We take out all that is possible at the compilation stage. In particular, we now have std :: array, which can be used with standard algorithms, but at the same time we avoid dynamic memory allocation.
- We manage memory with std :: shared_ptr, std :: unique_ptr.
By the way, about std :: shared_ptr. In
the Going Native'2012 review, there is a mention of why you should use std :: make_shared instead of the constructor std :: shared_ptr:
auto sp1 = make_shared<T>( args )
Rainer Grimm was not too lazy to compare the performance of different approaches, including the usual pointers, std :: shared_ptr and std :: unique_ptr.
3 auto st = std::chrono::system_clock::now(); for (long long i=0 ; i < 100000000; ++i){ int* tmp(new int(i)); delete tmp; // std::unique_ptr<int> tmp(new int(i)); // std::shared_ptr<int> tmp(new int(i)); // std::shared_ptr<int> tmp= std::make_shared<int>(i); } std::chrono::duration<double> dur=std::chrono::system_clock::now() - st(); std::cout << dur.count();
Got such a comparative table.
pointer type | real hardware | virtualization |
---|
native | 3.0 sec. | 5.7 sec. |
std :: unique_ptr | 2.9 sec. | 5.7 sec. |
std :: shared_ptr | 6.0 sec. | 11.8 sec. |
std :: make_shared | | 6.5 sec. |
Links
1.
Eric Niebler, C ++ 11 and No-Compromise Library Design2.
Out Parameters, Move Semantics, and Stateful Algorithms3.
Rainer Grimm, Embedded Programming with C ++ 11