5 ms·
...my compile times rarely take more than a minute, so I can't really relate to that, but exceptions will slow down execution and add an overhead to the binary'
by klingonopera 7y ago
...my compile times rarely take more than a minute, so I can't really relate to that, but exceptions will slow down execution and add an overhead to the binary's file-size.
- wvenable 7y agoExceptions don't generally slow down execution -- they usually have zero runtime cost if they're not thrown making them better than error returns for performance. However, the exchange is, as you said, that they do add a lot of overhead to the file-size.
- klingonopera 7y agoRegarding error handling, I agree with this author[0], and find the C-based approach much better than C++'s try/throw/catch methods. Regarding execution times, I don't know from first-hand experience, I did some research and found this[1]. The third sentence in that reply ("The error code is not sensitive to the percentage of occurrence") is AFAIK wrong (because of speculative execution, I believe?), but the rest seems quite solid. [0]: http://250bpm.com/blog:4 http://250bpm.com/blog:4 [1]: https://stackoverflow.com/a/52513707 https://stackoverflow.com/a/52513707
- vardump 7y agoSomething that generates extra code that ends up in the instruction cache during execution is not zero cost. There's cost to transfer it through memory and cache hierarchies and there's cost when it causes the CPU to drop some other L1C cache line.
- gpderetta 7y agoWell, if the exception is not thrown, no code related to the exceptional path goes into the instruction cache (not even checking for exception propagation). Assuming of course a non-completely dumb compiler that puts exceptional path code and unwinds tables in separate pages than hot code.
- vardump 7y agoTrue. I think I'll test whether use of exceptions can affect optimizations concerning register allocation and spilling, like function prologues and epilogues. Unwinding will also need to call destructors, and for that you'll need to have the object pointer somewhere in (stack frame) memory. But it might be in just a register. Unless, of course, the unwinding engine can look into registers as well. I guess it's not a huge deal either way, especially in 32-bit x86 code. For large register file systems it might be a different story, forcing otherwise unnecessary spills. Regardless, I'll find out when I got some time. Anyways, my point was more generic. So-called zero-cost abstractions are my pet peeve, because they're often not zero cost precisely because of larger generated code size. Typical microbenchmarks don't capture this, because their hot path can usually fit comfortably in L1 code and data caches.
- gpderetta 7y agoIn theory the optimizer can optimize exactly as if the exceptions where not there, in practice some code motion optimizations might be restricted across exception boundaries simply because it might be too much work to make it work correctly. So it is possible on some tests cases to measure a difference. Regarding spilling and register allocation, IIRC[1] the unwind tables contain a simple bytecode that is interpreted by the undwinder to fixup stack and restore registers (indexed by the current ip address), so no actual registration of object to destroy need to be done, nor does the frame pointer need to exist at all: the unwinder interprets the bytecode to recursively adjust each stack frame and registers to the expected values. [1] At some point I had actually learned to write unwind tables by hand, of course I completely forgot everything about that: look at trampoline_thunk at https://github.com/gpderetta/delimited/blob/master/delimited.hpp#L114 https://github.com/gpderetta/delimited/blob/master/delimited... even with extensive comments is still write-only code. It doesn't help that there aren't a lot of DWARF CFI tutorials around.
- wvenable 7y agoExceptions store the data to unwind the stack and run the handlers "out of band". Actually triggering the exception itself is expensive but that's an acceptable trade off as exceptions should only be used for exceptional situations.
- dragontamer 7y agoI'm no compiler expert, but I would expect that compilers would put exception-handling code on a separate 64-byte cache line. You only use up "cache" if you actually hit the cache. If you're on a different L1 cache line (and never execute), you'll never be in L1 instruction cache, maybe never even in L2 or even L3 cache lines. Not that I'm an expert on compilers... but whenever I look at assembly, there are lots of "NOPs" across the code. I've always assumed it was for some kind of boundary alignment, probably cache.
- vardump 7y ago> I'm no compiler expert, but I would expect that compilers would put exception-handling code on a separate 64-byte cache line. I'd sure hope they're on an entirely different page, not just cache line! Concerning compiler code alignment: they seem to place my code on 16-byte boundaries - for a good reason too, the smallest code size while keeping optimal 16-byte aligned branch targets. In past I actually had to drop to assembler to get 64-byte (cache line) alignment for functions (MSVC). GCC does have optimize pragma, like: #pragma GCC optimize ("align-functions=64") Although I want to point out one shouldn't usually worry about low level details like function alignment. Use profile guided optimization, etc. instead. Also remember due to L1 set associativity limitations excessive alignment can even cause pathological L1 churn in the worst case.
- Crinus 7y agoHeh, this reminds me of the Abrash quote about optimization mentioned a few days ago (from his black book): > We're so used to slow software that when a compile-and-link sequence that took two minutes on a PC takes just ten seconds on a 486 computer, we're ecstatic—when in truth we should be settling for nothing less than instantaneous response. (from https://github.com/jagregory/abrash-black-book/blob/master/src/chapter-01.md https://github.com/jagregory/abrash-black-book/blob/master/s...) Personally i'm annoyed when my compile times take more than a few seconds :-P