Live data from Hacker News

Current hardware trends make C++ exceptions harder to justify

open-std.org

501–510 of 516 posts

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

#501

Earlier quoted context omitted.

> Yes I do agree but my point is that if any exception is being thrown for the sake of being handled then your Audio code is bad. thank god ! then we both agree. > Generally your Audio loop should encounter no errors at all (it should be a pure process) and audio handlers should never lock mutexes yet I have seen my fair share of them in the wild. > My only point is that throwing an exception when there is no handler…

> and audio handlers should never lock mutexes yet I have seen my fair share of them in the wild. They are incorrect. Only bounded-time synchronization primitives can be used. E.g. lock-free queues. > every thread or event loop should always have a catch-all handler at top level. Two things. 1) There should be no reason for a properly coded real time audio loop to have a top level handler because exceptions should no…

> They are incorrect. Only bounded-time synchronization primitives can be used. E.g. lock-free queues.

yes, my point is that incorrect code exists in the wild, that's the world we have to live in.

> properly coded real time audio loop

most things aren't properly coded, and yet still useful

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

#502

Earlier quoted context omitted.

> 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 mu…

Are you sure? Single threaded 18-16ms (boost::LEAF) vs 19-23ms (exceptions) A better comparison is found here: https://lordsoftech.com/programming/error-codes-are-far-slow... > TL;DR On modern 64-bit PC architectures, C++ exceptions only add unreachable code with destructor calls into functions and their effect on performance is below 1%, but such low values are difficult to measure. Handling rare errors with return…

Your "better comparison" finds that error codes are slower than exceptions? It's right there at the top in bold even if you don't want to read the whole thing:

> TL;DR On modern 64-bit PC architectures, C++ exceptions only add unreachable code with destructor calls into functions and their effect on performance is below 1%, but such low values are difficult to measure. Handling rare errors with return values requires additional branching that slows down the program in realistic scenarios by about 5% and are also less convenient.

Also I see you "cherry picked" your counter example using the sqrt test, which is less influenced by per-call overhead. Using instead the fib test, which is basically just a test of call overhead, we get instead:

   12ms-14ms (exceptions) vs. 22-23ms (boost::LEAF)
Both the paper & your link are in agreement - exceptions are faster than error return values.

> 5% cost to using error codes. In exchange for that 5% you don't fall off a performance cliff if you hit a bunch of errors unexpectedly, and can confidently use them in hot paths and on CPUs with multiple cores.

You also get more fragility since error handling is now manual. I'd rather have performance and reliability, which only exceptions can provide. They don't provide that today thanks to the global mutex, but the point of the paper & related explorations is that that both can be fixed, and that fixing it provides a superior performing solution. And a more reliable one.

Unless you're arguing that it's better to just always have a 5% performance tax & manual, error-prone error handling? We shouldn't attempt to fix the toolchain at all? The paper isn't arguing that people should use exceptions today. The paper is arguing that exceptions should be fixed so that they can be used in the future.

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

#503

Earlier quoted context omitted.

That seems like an awfully short sighted argument. Less than 20 years ago we were all using single-core CPUs. Now most of us have at least 6 cores if not more in a battery powered handheld device that we don't even expect to do much compute work on (aka, smartphones). And 8-16 cores w/ SMT are not an unusual consumer laptop/desktop configuration. The articles suggestion that it's only a matter of time for 128+ core C…

128 cores is only 2x 64 cores, and 64 cores is a whopping 4x what AMD's top dog desktop CPU offers, so if you have to go this far for exceptions to be slow, then maybe they don't matter for most users.

Your math is a bit off, confusing threads & cores. 128 threads is only 4x of what AMD's top desktop CPU offers, and is what current AMD server CPUs offer in a single socket system. And over the past 20 years consumer CPUs have 32x'd their thread count. A 4x increase over the next 10+ years really doesn't seem all that far-fetched.

Also, the scaling problems show up far before 128 threads are used. The scaling issues start showing up at just 4-8 threads, depending on the error rate.

Also also, C++ is used in a hell of a lot more places than just consumer desktops. So the current limitations of consumer desktops is fully irrelevant anyway.

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

#504
post #498

Earlier quoted context omitted.

It suffices that exceptional situations are possible and must be checked for. It is true that in C++, as in Rust, it is much more common than in C to have very short functions that call other very short functions that, all composed together, do a job that, absent abstraction, might all be coded in a single larger function tailored to the specific use case; and the compiler squeezes out most of the calls and generates…

> Therefore, there are many more places where an error return report would need to bubble up through, and that would cripple performance to handle the naive way, without exceptions. Do you have any evidence for these claims? If a called function is quite long by itself, then there is hardly any added overhead if the client checks the returned code and that check would be "redundant". For example, if I make a syscall…

> wouldn't exceptions and stack unwinding have to do just as much work per stack frame? It can't really just skip over all frames in a single instruction.

Taking that back. I forgot for a second that we're focusing on the cases where the exception is not thrown.

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

#505

Earlier quoted context omitted.

> and audio handlers should never lock mutexes yet I have seen my fair share of them in the wild. They are incorrect. Only bounded-time synchronization primitives can be used. E.g. lock-free queues. > every thread or event loop should always have a catch-all handler at top level. Two things. 1) There should be no reason for a properly coded real time audio loop to have a top level handler because exceptions should no…

> They are incorrect. Only bounded-time synchronization primitives can be used. E.g. lock-free queues. yes, my point is that incorrect code exists in the wild, that's the world we have to live in. > properly coded real time audio loop most things aren't properly coded, and yet still useful

I see a difference between bugs and design flaws.

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

#506
post #498

Earlier quoted context omitted.

It suffices that exceptional situations are possible and must be checked for. It is true that in C++, as in Rust, it is much more common than in C to have very short functions that call other very short functions that, all composed together, do a job that, absent abstraction, might all be coded in a single larger function tailored to the specific use case; and the compiler squeezes out most of the calls and generates…

> Therefore, there are many more places where an error return report would need to bubble up through, and that would cripple performance to handle the naive way, without exceptions. Do you have any evidence for these claims? If a called function is quite long by itself, then there is hardly any added overhead if the client checks the returned code and that check would be "redundant". For example, if I make a syscall…

What you are calling "layers of cruft", other people call abstraction. That abstraction enables people to have code exactly tailored for a specific use without writing it over and over, slightly changed each time, for each use.

In C, of course, you have no choice; you write the whole function over and over. C programs are, e.g., filled with custom one-off hash tables, because you can't write a performant, general hash table library in C. People using C++ and Rust do not code their own hash tables, because they cannot match the performance of well-tested and tuned library components.

As a consequence, modern C++ and Rust coders get better-than-C performance for a lot less work, and ship with many fewer bugs, by relying on mature, well-tuned libraries. That is worth a lot of what you call cruft.

That said, it is not uncommon to find C++ and Rust coders aping what they see in general-purpose libraries by adding superfluous cruft in their own programs, that provides no such benefit. But that is a complaint for another day.

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

#507
post #506

Earlier quoted context omitted.

> Therefore, there are many more places where an error return report would need to bubble up through, and that would cripple performance to handle the naive way, without exceptions. Do you have any evidence for these claims? If a called function is quite long by itself, then there is hardly any added overhead if the client checks the returned code and that check would be "redundant". For example, if I make a syscall…

What you are calling "layers of cruft", other people call abstraction. That abstraction enables people to have code exactly tailored for a specific use without writing it over and over, slightly changed each time, for each use. In C, of course, you have no choice ; you write the whole function over and over. C programs are, e.g., filled with custom one-off hash tables, because you can't write a performant, general ha…

Somehow the discussion shifted away from the original topic...

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

#508

Earlier quoted context omitted.

Not in C++ I believe ?

https://en.cppreference.com/w/cpp/io/basic_ios/exceptions

That is manually throwing an exception if the file doesn't exist.

C++ stdlib does not throw an exception if a file does not exist. I agree with this philosophy because files not existing isn't an exceptional case.

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

#509

Earlier quoted context omitted.

Sure, but that in itself is also not an argument. The space of programming languages in general is moving forward and languages keep adding more (usually higher-level) features. C++ is mostly trying to keep up.

Adding features from literally every other language, just to create a mess - isn't really a selling point. Right now, to learn C++ in a generic way, you need to learn pretty much all of programming paradigms and all of their variations - which is not a thing I would consider a plus.

>Right now, to learn C++ in a generic way, you need to learn pretty much all of programming paradigms and all of their variations - which is not a thing I would consider a plus.

I disagree, I would recommend learning enough where the tool starts providing value to YOU for YOUR problem domain and then pause/resume as needed. The main purpose of any programming language is to be productive in it and use it to solve a problem. In my opinion, there is no reason to learn more than you need about C++ unless you were a compiler author, on the C++ standards committee, or something similar.

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

#510

Earlier quoted context omitted.

That would turn communicating between threads into communicating between VMs, which is a disastrous change in itself.

how do you know the threads need to communicate with each other?

How do you know they don't?
Post reply on HN