Live data from Hacker News

Current hardware trends make C++ exceptions harder to justify

open-std.org

441–450 of 516 posts

Re: Current hardware trends make C++ exceptions harder to justify

#441
post #415

Earlier quoted context omitted.

Without exceptions, you will hit a performance problem on every single call , successful or not. That is what happens at Google, and in Rust: almost every last call site in the whole system has a "if" check. I.e., it is both badly obscured, and also slow. You are arguing that programmers should not be obliged to make judicious choices. But that is exactly the job of every programmer. Dodging consequential choices pra…

I can't imagine error-checking if's being a source of slowness. How are exceptions generated in the first place? Using if's. And anyway, even well structured code is full of if's (e.g. array iteration), and it's not a problem. Especially for error-checking, when the error case is rare, the CPU will correctly predict the branch to take most of the time, so the cost of the if is negligible. The only call where if's sho…

That "if" that guards the throw is the same "if" as would guard the error return. It is the second "if", in the caller, checking the returned result, that up-to-doubles your branch-prediction cache footprint. On, yes, the hot path.

Program structure corruption is another problem. They add.

Bad code is a tax on all of us.

Re: Current hardware trends make C++ exceptions harder to justify

#442

Earlier quoted context omitted.

Low latency is not the issue per se. It’s more like being able to guarantee a worst case upper bound runtime. Maybe your system can tolerate indeterminate but rare worst case run times but many useful systems cannot. E.g. flight control systems but also ideally any interactive system.

Well i'm now working in a hard realtime domain (audio, noone dies when it goes wrong, but it's still hard realtime) and i've still got exceptions turned on. But no exceptions are thrown during runtime, they're there for exceptions. Yes, there's overhead in places, but we noexcept some code paths to reduce that overhead in some very hot code paths.

If you allow exceptions in your real-time audio loop then when an exception occurs the only useful thing to do would be to take down the entire process. Handling exceptions as a norm in your audio loop would be unacceptable because it could never be done in a way that would always meet the deadline. In that case, if you cannot usefully handle the exception, why have your exceptional situation cause an exception in the first place? You’re just as well off calling abort().

Re: Current hardware trends make C++ exceptions harder to justify

#443
post #402

Earlier quoted context omitted.

A language that has stopped responding to the evolving needs of its user community is a dead language. C++ is not a dead language. Your complaint is that it is not dead.

I read OP’s complaint as “it is no coherent”

That is code for "it is evolving and I cannot be bothered to keep up".

All languages that are actually useful evolve. They get features that other people need, and you don't, just yet. Some of those features do turn out not to be perfect, because they are made by humans.

Comparing an old language to a new language, the new language will have many fewer of those both because it leaves many old things behind, and because it gets benefit of hindsight for the rest. Give it time, and it will accumulate "incoherence" of its own; the faster it evolves, the faster that happens.

The alternative is for a language not to be used. Then, it can stay pristine and "coherent", and not useful.

This is the human condition.

Re: Current hardware trends make C++ exceptions harder to justify

#444
post #397

Earlier quoted context omitted.

This just spectacularly bad advice and policy. Point performance is the worst way to decide about error handling. The overlap between "things that fail and the caller knows something useful to do", and "things that fail and somebody maybe six levels back in the call chain might know something to do" is remarkably thin. Most things are the latter. Once in a while, it makes sense to provide one for each: (1) open a fil…

> Point performance is the worst way to decide about error handling. My point is exactly that. It's more important to have a single common way of doing error handling than it is to have a small perf improvement. That's why I recommend return values. You'll never hit a perf problem with them. Exceptions cannot be used in code hot paths (~thousands of iterations) when it's not a small perf problem anymore. Therefore, t…

> That's why I recommend return values. You'll never hit a perf problem with them.

> Exceptions cannot be used in code hot paths (~thousands of iterations) when it's not a small perf problem anymore.

You should read the paper in the link. Both of your claims here are exactly backward.

The problem is "just" that exceptions don't scale across multiple threads due to internally using a global lock. They are otherwise much faster than return values (4x faster in the trivial example)

Re: Current hardware trends make C++ exceptions harder to justify

#445
post #435

Earlier quoted context omitted.

I'm not convinced they're comparable. C++20 is adding a module system to C++. That's a major change to the compilation model. It is also adding concepts, a major change in the way templates are to be written. The very article we're commenting on is discussing how exceptions should possibly be replaced by another error report mechanism, several proposals are in flight for this. There's also the "destructive moves" pro…

> It is also adding concepts, a major change in the way templates are to be written. Indeed, instead of crazy tricks with SFINAE and tag dispatch, templates can be much easily written.

That's probably correct, I did not use concepts at the moment (stuck in C++14 right now). I certainly have my beefs with both features (modules that are orthogonal to namespace, no standard way to find modules, new and exciting ways of committing ODR violations, generally a complicated module system with quirks when there is so much prior art on modules in other languages, concepts being structural and not nominal, concepts being a "lower bound" on behavior and not an "upper bound" (thus not eliminating duck typing)), but my larger point is the scope of these changes to the language, not their (purported) benefit that I'm by and large unable to assess right now.

Re: Current hardware trends make C++ exceptions harder to justify

#446
post #432

Earlier quoted context omitted.

> When hinting branches gives you a bigger L1 cache footprint, it has a high cost. It was the same size on PPC, and on x86 using recommended branch directions (but not prefixes). > Compilers nowadays use code motion to implement branch hinting, which does not burn L1 cache. (Maybe code motion is what you mean by "hot/cold splitting"?) Hot/cold splitting is not just sinking unlikely basic blocks, it's when you move th…

It suffices, for cache footprint, for cold code to be on a different cache line, maybe 64 bytes away. For virtual memory footprint, being on another page suffices, ~4k away. Nothing benefits from being at the "end of the program". Machines do still charge an extra cycle for branches taken vs. not, so it matters whether you expect to take it. Negligibly few things never return; most of those abort. Performance of thos…

> Nothing benefits from being at the "end of the program".

It's not about the benefit, that's just the easiest way to implement it - put it in a different TEXT section and let the linker move it.

Although, there is a popular desktop ARM CPU with 16KB pages.

> Machines do still charge an extra cycle for branches taken vs. not, so it matters whether you expect to take it.

Current generation CPUs can issue one taken branch or 2 not-taken branches in ~1 cycle (although strangely Zen2 couldn't), but yes it is better to be not taken iff not mispredicted. (https://www.agner.org/optimize/instruction_tables.pdf)

> Negligibly few things never return; most of those abort. Performance of those absolutely does not matter.

Throwing an exception isn't a return, nor longjmp/green threads/whatever. Sometimes they're called abnormal or non-local returns, but according to your C++ compiler your throwing function can be `noreturn`.

Error path performance is important since there are situations like network I/O where errors aren't at all unexpected. If you're writing a program you can just special case your hotter error paths, but if you're designing the language/OS/CPU under it then you have to make harder decisions.

> Why should anyone care about predicting the catch block a throw will land in after all the right destructor calls have finished? We have already established that throwing costs multiple L3 cache misses, if not actual page faults.

More prediction is always better. The earlier you can issue a cache miss the earlier you get it back.

For instance, that popular desktop ARM CPU can issue 600+ instructions at once (according to Anandtech). That's a lot of unnecessary stalls if you mispredict.

And so its vendor has their own language, presumably compatible with it, which doesn't support exceptions.

Re: Current hardware trends make C++ exceptions harder to justify

#447
post #430

Earlier quoted context omitted.

> This is not accidental, and not a problem You're right it's not accidental, but the problem is that when you continually add new features you end up creating a confusing mess. Yes, the new features may respond to some need in the community, but by adding it you've also: - Introduced possibly unforeseen issues because features are never added in isolation; they interact with one another, and the more features you ha…

You are very confused. People not using the latest Standard are waiting for support within their particular environment, not because they want to stay with a less performant version of the language.

But they’re still not on the latest version…

Re: Current hardware trends make C++ exceptions harder to justify

#448
post #429

Earlier quoted context omitted.

No, a language can stay current by evolving to fit its purpose. A good example of this is Matlab. Matlab is older than C++ and is still heavily used today, enough that it's one of the few remaining programming languages to support an actual business. Matlab is not the same language it was in the 70s. But the core language is still largely about manipulating arrays and it does it well. It has evolved by adding functio…

Matlab usage has been in decline for many years.

Matlab is one of the top 20 programming languages in the world still after 60 years according to the TIOBE index [0]. It has maintained a large user-base and achieved profitability over this time, not by adopting every PL trend that has come and gone, but by adapting to new developments while staying focused on its essence as a language. It proves you can stay current without doing what C++ is doing.

Matlab's usage is down a bit since a peak at 2017, but over the last 20 years it's up over 300%, and it's done so by being a for-profit language. Mathworks is a billion dollar company, which is quite an achievement in the PL space in 2022.

Meanwhile C++ usage is up over the last couple years but the long term trend has been a steady decline over the last 20 years [1]. From 14% to a low of 4%, now back up to around 8%.

[0] https://www.tiobe.com/tiobe-index/matlab/

[1] https://www.tiobe.com/tiobe-index/cplusplus/

Re: Current hardware trends make C++ exceptions harder to justify

#449
post #396

Earlier quoted context omitted.

You can’t return null from a constructor (constructors have no return)

What dumb design. I thought the constructor returned a pointer to the memory created. No return? Stupid!

FWIW, constructors do not "create" (I assume you mean allocate) memory. That's the job of operator new. A constructor, given a block of untyped memory, will construct an object in it.

Re: Current hardware trends make C++ exceptions harder to justify

#450
post #435

Earlier quoted context omitted.

> It is also adding concepts, a major change in the way templates are to be written. Indeed, instead of crazy tricks with SFINAE and tag dispatch, templates can be much easily written.

That's probably correct, I did not use concepts at the moment (stuck in C++14 right now). I certainly have my beefs with both features (modules that are orthogonal to namespace, no standard way to find modules, new and exciting ways of committing ODR violations, generally a complicated module system with quirks when there is so much prior art on modules in other languages, concepts being structural and not nominal, c…

Modules are mostly working on VC++, no quirks needed. In fact, I only use modules for my hobby coding now.
Post reply on HN