Live data from Hacker News

Current hardware trends make C++ exceptions harder to justify

open-std.org

491–500 of 516 posts

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

#491
post #482

Earlier quoted context omitted.

Since this is about immutable "side car" data structures used during unwinding: could this be achieved using a soft ABI transition as opposed to a hard, flag day ABI break? Basically, going forward the compiler would emit two versions of the unwinding tables by default: the legacy one and the one that allows fixing the thread contention issue. The unwinder is changed to use the efficient version by default with the a…

That might work. It would be yet another thing that would slow down compilation (link phase in this case) but not the worst. Compilers would have to generate both forms forever (except for new architectures) but probably that wouldn’t be terrible.

It only took ~two decades to remove a.out support from the Linux kernel :)

(I wonder when software engineers will more commonly think about their work on a generational time scale. Like how the cathedral builders of old must have thought about their work...)

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

#492
post #477

Earlier quoted context omitted.

Which is what I said. And I still don't see how most code that potentially returns errors would be on a hot path. Code that is really on a hot path should probably not call into generic code anyway, and/or that called code should be inlined. I don't know, as a C programmer, somehow I rarely run into these situations where I have to check error return values. I think the reason is that I work hard to avoid wrappers ar…

Inlined code still has all the "if" checks of the original code, just without the actual "jsr" and "ret" instructions in between. Comparing a good C coder to a bad C++ coder is meaningless: By definition, a bad coder makes bad choices, whatever the language. Bad code is slow in a place where speed matters. It is improved by making it fast. Language choice does not affect this. What language choice does affect is whet…

I'm not sure what you had in mind, but this little example is compiled using a single test: https://godbolt.org/z/bcqPWEn4a

I still can't imagine a situation where speed matters and where exceptional situations are likely and also hard to handle in a performant way with explicit error checking. Do you have any examples?

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

#493

Earlier quoted context omitted.

> Surely you agree that it's better to have this throw an exception, and a big try.. catch around your audio callback so that just this tick 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. Generally your Audio loop should encounter no errors at all (it should be a pure process) so what the OP is saying is that excepting/aborting is fine i…

> 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 not be thrown because they cannot be guaranteed to be handled within the necessary time constraints.

2) top level exception handlers divorced from context cannot be handled, only ignored. Ignoring exceptions is very dangerous because there is generally no way for the top level handler to be sure that the rest of the program is in a correct state (unless it knows all code is exception-safe, which is rare). Continuing to run can result in data corruption. Exceptions leaving the context that has the information to handle them is a programming error, just like a failed assertion.

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

#494
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…

> I can't imagine error-checking if's being a source of slowness.

The overhead of doing this is measured in the article itself.

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

#495
post #44

Begs the question: Why C++? Legacy projects (I am not being pejorative, they are important) which must be maintained aside, should not C++ be deprecated? We have many new languages, we always had C. What does C++ give us in 2022 that makes up for the enormous cognitive load of understanding and keeping up with it.

The ecosystem is frequently more important than the language.

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

#496

Earlier quoted context omitted.

How many people actually use a 128 core machine though? The absolute biggest AMD Threadripper you can get only has 64.

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.

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

#497
post #494

Earlier quoted context omitted.

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…

> I can't imagine error-checking if's being a source of slowness. The overhead of doing this is measured in the article itself.

As far as I can see, only the overhead of throwing exceptions is measured. Not error-checking if's (which might be quite hard to measure).

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

#498
post #477

Earlier quoted context omitted.

Inlined code still has all the "if" checks of the original code, just without the actual "jsr" and "ret" instructions in between. Comparing a good C coder to a bad C++ coder is meaningless: By definition, a bad coder makes bad choices, whatever the language. Bad code is slow in a place where speed matters. It is improved by making it fast. Language choice does not affect this. What language choice does affect is whet…

I'm not sure what you had in mind, but this little example is compiled using a single test: https://godbolt.org/z/bcqPWEn4a I still can't imagine a situation where speed matters and where exceptional situations are likely and also hard to handle in a performant way with explicit error checking. Do you have any examples?

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 object code as if for that single, longer function. 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.

It might be that some languages that have a native "result" type, and automatically generate checking code at the call site, can squeeze out most of the intermediate-level checks when composing inline functions together, e.g. if actual errors mostly occur at leaf nodes of the call tree. That could mitigate the heavy overhead cost of the method. But I don't know if any compilers do such an optimization, or if they do, how well it really works. Coding an optimizer is hard.

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

#499
post #498

Earlier quoted context omitted.

I'm not sure what you had in mind, but this little example is compiled using a single test: https://godbolt.org/z/bcqPWEn4a I still can't imagine a situation where speed matters and where exceptional situations are likely and also hard to handle in a performant way with explicit error checking. Do you have any examples?

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 and check the return value, there will be a duplicated checking effort with the kernel code in a way - but compared to the cost of calling into the kernel that overhead is a negligible cost for the benefit of modularization (kernel vs userspace application). This overhead will be very close to unmeasureable, and does not justify the introduction of exceptions which are an additional mechanism to return values which introduce syntactic and binary incompatibilities (i.e. non-orthogonal functionality).

Oh, by the way - 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.

I think the best solution to cruft is generally to not have it in the first place - instead of introducing a mechanism to skip over layers upon layers of "abstraction", it's better to just not have these layers. There should not be a large call chain that unwraps multiple stack frames in a row. The best code is code that just does what needs to be done in a straightforward way without using any library cruft. Nothing to "optimize" away this way.

Give any concrete example where exceptions are useful in order to work around cruft, and we can see if there is a better way to write it that does not require exceptions.

Frankly it seems hilarious to me that we're having a discussion about optimizing a few if's because they allegedly add too much overhead for the work of skipping over layers of cruft.

In the past years I have seen the need to use longjmp() (which is in a way a mechanism to get exceptions for C) only one single time, when I was coding an interpreter that got embedded into a longer running application. I didn't know how to skip through recursive layers of parsing calls in the recursive descent parser. But I still feel like there is a better way to write the parser (like, pushing work to parse to a data structure instead representing it as a nested stack frame). This could also benefit error reporting for example.

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

#500

I manage 1.2MLOC C++ developed over 25 years. I am pleased to say we never had to use exceptions. Just check the return value.

How do you guys handle using other libraries? Everything I can see uses stuff like std::vector and the like at API boundaries, and I'm not aware of a way to construct an std::vector without throwing an exception.

We use the STL. We have never observed an exception thrown.
Post reply on HN