C++ Annotated: January 2021
Hi all,
Welcome to the January edition of C++ Annotated and its companion, the No Diagnostic Required YouTube show!
You can read us, listen to us, or watch us! Here’s how:
- Read the digest published monthly on this blog (use the form on the right to subscribe to the blog).
- Subscribe to C++ Annotated emails by filling out this form.
- Watch the No Diagnostic Required show on YouTube. To stay tuned, follow us on Twitter.
- Listen to us in most podcast players by searching for "No Diagnostic Required" (see the list of supported players).
January news
- Faster C++ iteration builds in Visual Studio
- Global Data Flow Analysis in CLion
- News from WG21 mailing
- Conferences, all Online
- News from other podcasts
- A webinar with Clare Macrae on testing
- Ray Tracing in pure CMake
Watch the new episode of No Diagnostic Required below, or just read on!
Faster C++ iteration builds in Visual Studio
The Visual Studio team recently posted about speeding up edit-build-debug (“inner loop”). They have done some great work to improve the linking time in two major areas.
One area concerns improving the algorithms behind Program Database (PDB) creation and Debug Interface Access (DIA) (since Visual Studio 2019 v16.6). The biggest speed improvement was achieved by caching search results by Relative Virtual Address (RVA) for the previous request and using that cache the next time. Other algorithm optimizations also increased linking speed.
In the end, the team reported impressive results:
- 2X speed improvement of initial PDB load.
- Up to 1.5X speed improvement when full linking.
- Up to 4X speed improvement when switching the active function on the call stack with many variables.
- 2X speed improvement when entering the break state after a single step.
The other main improvement area is speeding up the worst-case Incremental Linking time (since Visual Studio 2019 v16.7). On huge projects, in the worst case scenario, incremental linking can be slower than full linking. To mitigate this, the team had the idea to cache the results of earlier debug information generation and reuse it during subsequent links. This approach yielded speed improvements of 2–5X. There are some downsides though – the PDB file becomes larger as it stores the cached data, and the first/clean link of an incremental build takes slightly longer because the cache must be built.
Aras from Unity highlighted this news on Twitter. He noted that in Unity they were using fastlink (a way to improve linking by keeping debug info in original .obj
files). But they had issues with third-party code that did not understand the debug info format. They have moved away from that since VS 2019, but they have suffered from slower debugging as a result. But with these optimizations, linking a full Unity editor in release config takes only about 20 seconds, which is a great improvement – and they can now avoid fastlink.
Global Data Flow Analysis in CLion
One more piece of algorithmic magic is the new Global DFA in CLion 2021.1 EAP. The very first DFA in CLion was moved to Clangd-based language engine last year, which improved the accuracy a lot. The next big step now is introducing the interprocedural dataflow analysis, working inside the Translation Unit (TU). This new DFA handles function parameters/arguments, return values, fields, and global variables.
Global DFA enriches many existing inspections, such as dead code (when, for example, the function call only happens under an always-false condition, in which case the function body is dead code), null dereferencing, dangling pointers (especially when pointers are cleaned/deleted in a separate function), escape and unused analysis, and more. In addition, it makes new inspections possible, like unreachable call sites (all function calls are unreachable), constant function results, and constant function arguments.
The analysis was challenging to implement, but we managed it. And what’s more, we optimized the algorithms and reduced the number of timeouts for DFA (when the analysis is cancelled after 5 seconds), as well as the algorithm time itself. This blog post has more details, including charts with the performance measurements.
News from WG21 mailing
The January mailing from the C++ Standards Committee has about 30 papers to be discussed – mostly continuing revisions, but also some new papers. Here are a few highlights.
P0447 – std::colony
This is definitely not a new paper – it’s on revision 12 and has been progressing since 2016! But it did get a bit of attention on Reddit recently and was mentioned on a recent CppCast, so let’s take another look at it.
Colony is a simple but very useful sequential container. We’re used to thinking of std::vector
as being the “default” container for most of the instances when you just need to hold a bunch of objects in memory. But it has some properties that can be poor trade-offs in many cases. In particular, insertions – even at the end of the vector – may (mostly unpredictably) cause reallocations and arbitrary copying, and any pointers, references, or iterators to items within a vector are invalidated.
If you don’t care about ordering too much and can afford very slight iteration overhead, Colony may be a better choice. Rather than being contiguous in memory, Colony manages blocks of memory, so insertions never require reallocation (but may require the allocation of a new block). Furthermore, any given slot may contain an object or a skip flag (in fact a skip run), so even removing items doesn’t cause subsequent items to be copied back. Skipped slots can be reused for subsequent insertions, so for many use cases most of the locality advantages of Vector are still met!
This new revision of the paper is mostly fixes and corrections – a good sign that the proposal is reaching maturity.
P2232 – Zero-Overhead Deterministic Exceptions: Catching Values
The title, here, is a play on p0709 – “Zero-overhead deterministic exceptions: Throwing values”. In fact, the number of that paper is the very first word in this proposal (at least this initial revision of it). Whereas p0709 proposes a new error-handling mechanism (which may look somewhat similar to our current exception handling, but isn’t), p2232 proposes an optimization (and extension) to the existing mechanism, which only kicks in if you catch by value. The mechanism itself is essentially what the new Boost.LEAF library, which we looked at last month, implements (it’s being proposed by LEAF’s author), but in this case the mechanism is baked into the language (taking advantage of the possibility of further optimizations in doing so).
This very interesting proposal gives us a lot to think about. Personally (Phil speaking) I don’t necessarily agree with all of the claims made in the paper, but, perhaps more importantly, it doesn’t address what I believe to be the biggest problem with exceptions – the lack of visibility in signatures, leading to a lack of local reasoning. Nonetheless, I’m keen to see how this is going to contribute to the debate.
P2168 – std::generator: Synchronous Coroutine Generator for Ranges
This is the first revision of this proposal. It was originally proposed last year, but we haven’t talked about it before.
Coroutines made it into C++20 as a language feature, but so far this feature is more like a toolkit for building different kinds of coroutines. To be useful in application code, it needs library support. Lewis Baker has maintained the cppcoro reference library for some time, and if you want to use Coroutines today, this should probably be your first stop. But this paper, authored by Lewis (along with Corentin Jabot), is an important first step toward getting some of these much-needed facilities into the standard.
Generators are just ways of producing lazy sequences of values. This paper proposes an implementation that plays nicely with Ranges, and can also be recursive (it can co_yield
other generators of the same type, including itself). For example, from the paper:
generator<int> visit(Tree& tree) {
if (tree.left) co_yield visit(*tree.left);
co_yield tree.value;
if (tree.right) co_yield visit(*tree.right);
}
P2272 – Safety & Security Review Group
This was actually from the December mailing, but we didn’t discuss it then. Safety and Security have always been important concerns. But recently, larger scale C++ codebases are being put into more and more safety critical systems, like cars. As more of our lives are potentially exposed due to security vulnerabilities, there’s a need to take the concern for security to the next level! Best practices, and following strict standards, such as MISRA C++ or AUTOSAR, are a start. But the nature of the language itself still poses a problem, particularly with so many ways to shoot yourself in the foot, in addition to so many areas of undefined behavior that we rely on for performance reasons.
So starting a review group within the standards committee seems like the right thing to do. This paper proposes an invitation only group of industry experts to advise the committee. To those who worry this may compromise C++’s core tenets of zero-cost abstractions, and who want to be sure not to pay for what they don’t need, the paper wraps up by saying:
“The ultimate goal for this group is to help guide the development of Modern C++ towards a safer language that still has the speed and power we need for high performance applications”.
Conferences
ACCU 2021
In the current pandemic situation, events are bound to happen online. Together with other Program Committee members and organizers, Anastasia Kazakova is happy to announce the full schedule of ACCU 2021, as well as a significant 50% discount on our usual fees as the conference goes virtual. The conference will be held from Tuesday, March 9, through Sunday, March 14, including pre- and post-conference workshop days. And it’s packed with dozens of great talks not only about C++ goodies (though there are certainly a lot of talks on C++20!) but also on general programming techniques. The keynote speakers include Kevlin Henney, Patricia Aas, Sean Parent, and Emily Bache.
Sad news also came in January. Russel Winder, a genius programmer, enthusiast, and former ACCU Conference Chair, has passed away. We will remember Russel for his contribution, passion, and energy, and we send our sincere condolences to his family.
C++Now 2021
It’s now officially been announced that C++Now 2021 will be held completely online, from May 2 to May 7, 2021. Registration and the Call for Submissions are now open. This is one of the more interesting events to move online as, traditionally, it has seemed a little more exclusive – not because it is unwelcoming, but simply because the physical location has been expensive to get to and stay at (especially for international travellers). It also has a reputation as an “experts” conference, due to its roots as a Boost developers’ event. But, while the sessions definitely tend toward the deep and hardcore, developers of all experience levels will get something out of the event – and now many more people can give it a try. Just be prepared for the more audience-interactive nature of many of the talks.
C++ on Sea 2021
As many others, C++ on Sea has announced an online event again this year, but it’s also implementing a new format! It will be a 3-day event, with one day for "classic" conference talks (including the ever popular lightning talks), and two days for different types of workshops (including half-day ones). The ticket options include a wide variety of combinations to cover the range of the priorities one may have in this situation. The CFP is not yet open, but is expected to be soon.
Podcasts
Last month we introduced another new podcast: Two’s Complement, hosted by Matt Goldbolt and Ben Rady. At the time we suggested it was more of a games programming podcast. Actually it didn’t categorize itself at all, and so far it has evolved into more of a set of stories and discussions about different types of testing, as well as design principles. One of the recent episodes even guest-stars James Grenning, who talks about TDD with embedded C and C++, as well as the Agile Manifesto. Do check it out if you haven’t done so already.
And speaking of design principles, the SOLID principles are also the main topic of a recent episode of CppCast. Klaus Iglberger comes on to tell us why they are still relevant today, even in C++.
A webinar with Clare Macrae on testing
And while we are still on the topic of design principles and testing…
Everything started with Arne Mertz’s "Refactoring C++ Code" webinar, where he stated that tests are essential things to have prior to refactoring the code. They are necessary, as they are the way you confirm you are not breaking the code. But there was a question then "What can we do if we don’t have tests on the project and can’t easily check the changes introduced by refactorings?". As a core contributor to the Approval Tests for C++ library, which makes it really easy to cover legacy code with tests, Clare will try to give you an answer. She will be adding tests for untested code and checking their coverage.
The webinar is planned for February 16. Register, mark the date in your calendar, and join us!
Ray tracing in pure CMake
593 lines of code in a simple CMakeLists.txt is all it takes to code a true ray tracer! The CMake language is often blamed for being inconvenient and prone to issues. Well, here is a full tracer written in it! CMake’s math commands are nice but can only do integers, so they do fixed point arithmetic, while also computing square roots, vector operations in CMake, and more. For multi-core rendering, invoke sub-processes with the execute_process
command.