Back from CppCon 2016

Quarkslab was present at CppCon 2016, presenting general thoughts on the C++ optimization process and how much the so-called zero-cost abstraction relied on the compiler implementation, and not on the standard. Now comes a humble report from this great event!

Going to the US from France, back and forth, in less than 6 days, is a challenge on its own. Trying to follow top-quality talks of one hour on top of this resemble to the iron-man of C++ :-)

I was there to present a 1-hour talk, «C++ Costless Abstractions - the Compiler View». The slides are online (and yes, Bjarne Stroupstrup was in the audience! Achievement unlocked!)

The organization was great. Period. So many tracks, plus the poster session, the lightning talks, and the C++ challenge provided enough material for more than a week :-/

Also, when you go to CppCon, the bring home message seems to be: in the end, I hardly know a lot about C++. Feed for thoughts for the upcoming months!

SCM Challenge

A few C++ Puzzles, some require algorithmic knowledge, some require a good understanding of the language, and some cannot be overcome without a broad view of the Standard Library. I had a lot of fun solving them, but I missed a few talks because of them too... The puzzles are still available at https://scmchallenge.com/, so have fun!

Poster

I spent quite a lot of time with the author of uftrace, who was presenting a very nice poster about a tool to trace a program and gather user calls and build the call graph. The underlying trick is nice: would I be asked to implement this, I would certainly go for an LLVM Pass that adds the relevant instrumentation hook. Instead, they built their tool relying on the instrumentation already performed by the -finstrument-functions option that adds profiling hooks to the binary, then hook on the support library libgcov. Nice! (Brest!)

Talks

Here is a list of the talks I attended too, with some comments and/or insights.

Undefined Behavior is Magic

[summary_0] [video_0]

Undefined behavior is a strange beast: standardization of the lack of a well-defined behavior! If that sounds like a nonsense to you, enjoy the great blog post trilogy that starts here: http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html.

So this talk leads us to a walk into the marvelous world of undefined behavior. Not that much surprising stuff: basically if you rely on something that's undefined, undefined things can happen. The bring home message is simple: use -Wall -Werror -Wextra and you should be okay.

Hybrid Data Structures

[summary_1] [video_1]

A fascinating talk about LLVM core data structure, many of them are used in the everyday task of LLVM developers. Many tricks implemented smartly by the LLVM Community, like Small Vectors/Set/Map that use either the stack or the heap depending on their actual size, the well-known trick that uses pointer alignment information to store some info in the less significant bits. Funny enough, back in the days, the opposite was done (i.e. storing information in the most significant bits) in BIBOP Typing.

I did not know about PointerUnion, used in TinyPtrVector, namely This class is specialized for cases where there are normally 0 or 1 element in a vector, but is general enough to go beyond that when required. Wow. The trick here is to store two types in the PointerUnion: the element type and the vector type, so that if one only has an element, it can be stored in the PointerUnion, otherwise it gracefully degrades to a vector.

To practice, I implemented a variadic (limited) version of PointerUnion. A good way to practice with the new C++14/C++17 features!

Extern C

[summary_2] [video_2]

What would you expect of a talk about talking to C programmers about C++ in a C++ Conference? Hundreds of technical arguments? C bashing? Not at all! This talk takes a fascinating approach, stating that moving from C to C++ is a human problem, not a technological problem. A real troll slayer: if you want some C dev to adopt C++, you need to understand their mindset, and understand what they love about C and show them they can do it better in C++! I did not expect this kind of talk at CppCon, and wow again! For the record, during the question session, the author admitted that if what a C dev loves is simplicity, then C++ is not a good alternative ;-).

boost.simd

[summary_3] [slides_3]

If you're familiar with SSE, AVX, NEON and the likes, you know the pain of writing portable high performance kernels. You generally end up with something like this:

for( int i = 0; i < size; i += 8)
{
  __m256 v0_avx = _mm256_load_ps(&data0[i]);
  __m256 v1_avx = _mm256_load_ps(&data1[i]);
  __m256 r_avx  = _mm256_add_ps(v0_avx, v1_avx);
  _mm256_store_ps(&res[i], r_avx);
}

With the proposed solution, you end up with something that:

boost::simd::transform( &data[0],&data[0]+size, &data1[0], &res[0], [](auto const& a, auto const& b) { return a+b; });

OK, I should not be there, I already know the guy, and we're using Boost.simd in pythran. But this gave me time to solve the challenges ;-)

Future of Concurrency

[summary_4] [video_4]

A lot of things happening in C++14 and C++17 for multicore machines and to exhibit a nice multithreading model to C++ developers, with reader-writer mutex, parallel version of some STL algorithms, concurrent containers and so on. Note that for parallel algorithms, executor and schedulers seems to be exposed, for fine grain control. Combined with Boost.SIMD, you get a nice way to implement parallel, vectorized code! I wonder how much Intel's threading Building Blocks inspired these algorithms, and how they compare? Being able to customize executor and schedulers certainly mean the work-stealing policy used by TBB can be used there too.

I have to dig into building Data Flow Graph based on futures and their chaining through next, when_any, when_all and the likes!

Lock free

[summary_5] [slides_5]

Before attending the talk, I thought « yes, lock free algorithms and data structures are so coool ». I was well aware that they did not change the critical point, rather decrease the cost of synchronization, but still; After this talk, it's pretty clear that:

  • Lock free is a small grain optimization, not relevant for high-level parallelism.
  • It only decreases data sharing overhead.
  • Mutex are generally* ok, and much safer to use correctly.

An interesting remark on benchmarks: benchmarks must address normal cases, not corner cases; At least that's what the user sees.

Writing high quality code

[summary_6]

A lot of interesting tip/advice, I think I'll take inspiration from this talk! Among others:

  • contracts as a way to document: makes the contract readable (aka no doxygen)
  • doc = code only holds for small projects / no deep call stack
  • build on recognizable pattern (culture)
  • paying innovation taxes: conf/books/code reviews + modernize code base
  • know how to say no to the manager

I particularly adhere to and already put in practice the last two points :-)

Commodore 64

[video_7]

Very nice and interactive talk, be amazed at how a nice combination of language feature, compiler knowledge and skills make it possible to generate low-memory footprint and efficient code from C++ to... Commodore 64 binaries :-)

A full glass of constexpr Mojo! I played a bit more with the idea to leverage on a black hat talk and provide compile-time string obfuscation.

Note: the author did not write a full LLVM backend for the Commodore 64 processor, a.k.a m6502, but dumped the x86 assembly then (uggh) translated it to 6502. A real backend is in development <https://github.com/beholdnec/llvm-m6502> though.

C++ Challenge

I'm pretty sure my solutions are not the best ones, and I don't want to spoil the challenge for those who attempt it. So I'll just showcase one challenge, it's up to you to solve the others!

C++ pirates / Level1

In this challenge, we are provided with unmodifiable code, as follows

The goal is to provide an implementation of skeleton_key() that returns an instance of secret_cove::hidden_password although this class is private. In C++03 ('cause pirates are old school, you know).

My solution:

The idea is to use template pattern matching to retrieve the type of the first argument of secret_cove::key_to_next_level. The argument type is private, but the method is public! Once we get the type, we can form a pointer to it, which is enough to get the type information we wanted!

I could have used something better than a macro for skeleton_key, but oh, pirates are not famous for following the rules, right?

Conclusion

If you feel confident in C++, come to CppCon, you'll realize the road is long ;-)

Thanks

Adrien Guinet and other Quarkslab reviewers for their reviews, Joël Falcou for the enlightenment, and of course CppCon organizers and Team for the great job!

General Resources

And if you're French and interested in C++, have a look to the C++ French user group

Comments