Live data from Hacker News

The Sad State of Debug Performance in C++

vittorioromeo.info

61–70 of 111 posts

Re: The Sad State of Debug Performance in C++

#61
The urge to have basic language features not be part of the language, but instead be part of the standard library is responsible for a lot of the less than stellar parts of of C++. Std::move/forward are particularly obvious cases, but you get similar accessing members of tuples, etc.

Wanting to keep things in the standard library rather than the language itself means that you have to compile large amounts of template hell for a wide array of basic things which hurts build time even in debug modes, and then as this article says you end up with no-op operations that become calls. You also can’t easily debug any of this because you end up with absurd layers of template nonsense for what is again basic functionality.

You can compile with -O1, but that then inlines things that aren’t part of the standard library that makes debugging of the actually relevant code annoying (this is what the debug llvm and clang debug builds do), as it inlines your own code and also means that you lose variables all over the place.

Re: The Sad State of Debug Performance in C++

#62

Earlier quoted context omitted.

It's not just inlining. With -Og (clang or gcc), the debugger frequently can't even tell me the value of function arguments because they've been "optimized out".

Just want to remind you that `-Og` in Clang is not representative here, as it's exactly the same as `-O1` -- they implemented support for the flag just to ease transitions between GCC and Clang without having to filter out flags, but it doesn't provide any debugging-specific advantage.

Yes, those who think -Og is no good because they are clang users should perhaps file bug reports or contribute improvements instead.

Re: The Sad State of Debug Performance in C++

#63
post #60

The author needs to learn about the -Og switch, which can be used together with debugging. It can be thought of as "do those optimizations that don't interfere with debugging". I verified with Godbolt that this suffices to eliminate the call overhead.

Did you even read the article? I mentioned '-Og' several times and its shortcomings.

Re: The Sad State of Debug Performance in C++

#64

I've been using C++ since 1993. I still don't understand how I've written all this code and never once found myself using, or wishing I could use std::move. Presumably my code has been less than optimally efficient or something, because it seems that most people talking about "modern" C++ view it as absolutely central to the language.

> Presumably my code has been less than optimally efficient or something Yep, it was either less efficient than it could be, or more clunky, or incorrect. I remember back when boost was still a thing, everyone using boost::shared_ptr indiscriminately. Refcounting has a very nontrivial cost to it if implemented correctly. Things like rvalue refs and std::move allow to properly implement the concept of "ownership trans…

I've been using boost::shared_ptr for 22+ years. My code has no concept of ownership transfer, ever. The reason for shared_ptr in our codebase is not to move ownership around, but to ensure correct lifetimes. For examples, objects in the model cannot die until the view has dropped references to them.

Re: The Sad State of Debug Performance in C++

#65
post #62

Earlier quoted context omitted.

Just want to remind you that `-Og` in Clang is not representative here, as it's exactly the same as `-O1` -- they implemented support for the flag just to ease transitions between GCC and Clang without having to filter out flags, but it doesn't provide any debugging-specific advantage.

Yes, those who think -Og is no good because they are clang users should perhaps file bug reports or contribute improvements instead.

Most game developers have to target Windows, and the main compiler there is MSVC. The other viable alternative is `clang-cl`, which doesn't have `-Og` either.

Bug reports have been filed, especially against MSVC, but they have been largely ignored over the years. AFAIK, MSVC is not open-source so improvements cannot be contributed either.

Re: The Sad State of Debug Performance in C++

#66

I've been using C++ since 1993. I still don't understand how I've written all this code and never once found myself using, or wishing I could use std::move. Presumably my code has been less than optimally efficient or something, because it seems that most people talking about "modern" C++ view it as absolutely central to the language.

You can absolutely write the same programs without std::move(), using out parameters for objects of expensive construction. Move semantics were introduced because they're a clear ergonomic win.

Gotcha. Probably the best explanation I've seen, thanks for that.

Re: The Sad State of Debug Performance in C++

#67
post #60

The author needs to learn about the -Og switch, which can be used together with debugging. It can be thought of as "do those optimizations that don't interfere with debugging". I verified with Godbolt that this suffices to eliminate the call overhead.

Did you even read the article? I mentioned '-Og' several times and its shortcomings.

I read it, but too quickly. Sorry. As you say, the main problem is that only gcc has a usable implementation; the other issues, for me, are an acceptable tradeoff (reasonable speed, but sometimes difficulty because inlining hid something).

Re: The Sad State of Debug Performance in C++

#68
post #35

I ran into these problems with std::unordered_map. While developing my game, I would always run it in debug mode because I need to debug it. Loading a game world was taking around 12 seconds, and it was beginning to grate on me because of the increased iteration times. So I decided to profile it and see what was taking so long. I compiled in release mode to begin debugging, and it magically took the world load time d…

Isn't it just a matter of /D_ITERATOR_DEBUG_LEVEL=0?

I think that won't work because all objects limited together have to use the same debug iterator level.

But you can go the other direction: start with release mode (make a separate build profile if you like) and turn on all debug features except debug iterators (and the debug CRT).

Re: The Sad State of Debug Performance in C++

#69

I've been using C++ since 1993. I still don't understand how I've written all this code and never once found myself using, or wishing I could use std::move. Presumably my code has been less than optimally efficient or something, because it seems that most people talking about "modern" C++ view it as absolutely central to the language.

std::move is not only about performance. It is about being able to disallow destructive copies of certain types. I.e. unique_ptr can not be copied, and auto_ptr can. Can you write perfectly functioning code without these features? Sure! You just have to be accurate. Same with performance. Where nowadays simple std::move() on a return value suffices you had previously explicitly to pass the object/vector with which yo…

Note that you don't even have to std::move a return value in almost all cases. (The very much non-language-lawyer explanation is that local variables are automatically moved from when you return them.)

Re: The Sad State of Debug Performance in C++

#70
post #2

> Even if -Og was ubiquitous, it is still suboptimal to -O0: it can still inline code a bit too aggressively for an effective debugging session. IMO, the problem is not so much the inlining, but the sad state of the optimization passes losing track of many things and producing useless debug info.

It's not just inlining. With -Og (clang or gcc), the debugger frequently can't even tell me the value of function arguments because they've been "optimized out".

I feel your pain. In those cases, you have to try and figure out what the assembly is actually doing and how it relates to the original source code.
Post reply on HN