7 ms·
I'm still waiting on an A:B test that shows that UB in the compiler makes my computer run faster.
by pizlonator 10y ago
I'm still waiting on an A:B test that shows that UB in the compiler makes my computer run faster.
- benchaney 10y agoWhat?
- to3m 10y agoThe point is: people are quick to say that taking advantage of undefined behaviour in the modern style is necessary to get best performance, and that this is worth the bother. But others (and I expect this person to be one of them) feel that perhaps good performance could be attained by some other route, one that doesn't involve the compiler stripping bits of your code out on an unanticipated technicality that requires ten paragraphs of legalese to explain. Especially not when the justification is something like "this would be hard to support on 1s complement" ;)
- the_why_of_y 10y agoYes, and this is why some of those others have designed the Rust language so that they can write programs that run fast without worrying about those tens of paragraphs of legalese. Same motivations for D, Swift and Go, except you get a bit less performance due to need for GC.
- marvy 10y agoI think what pizlonator meant is that some languages like C have pervasive undefined behavior. (For instance, INT_MAX + 1 is allowed to erase your hard drive.) The claim is that this allows compiler optimizations that would otherwise not be possible. The question is: how bad would that be? Let's turn off all these optimizations and see how much the benchmark scores drop. If everything is twice as slow, then maybe this undefined stuff is worth it. If everything is one percent slower, then maybe it's not.
- DrJokepu 10y agoI think the performance implications of bounds checking are fairly well studied.
- nickpsecurity 10y agoThat part of the field is still in exploration phase. The reason is that you can mix run-time checks with no checks for performance enhancement. Static analysis and other schemes are used to prove specific code doesn't need checks. The rest get checks automatically. Performance varies per scheme applied with overhead going down significantly over past decade. We don't yet know the answer on just how much spatial or temporal safety we can get at what cost.
- pizlonator 10y agoYou heard me. I'd be happy to explain any of the individual concepts if you are still confused.
- deleted 10y ago[deleted]
- paulddraper 10y ago-Ofast will produce noticeably faster programs by loosening the definitions of IEEE math.
- nickpsecurity 10y agoWill it do that without violating correctness? Are these necessary or unnecessary rules?
- AnimalMuppet 10y agoIf I understand correctly, it means that the math no longer fully conforms to every aspect of the IEEE spec. You lose some things like bits of precision in some operations, graceful underflow (where you keep as many bits as you can), and so on. These rules are unnecessary - for most problems. If you have a problem where you need them, though, your calculations will silently produce garbage without them. I think (but I am not sure) that most of the time, if you need full IEEE arithmetic for your problem, you know that you need it.
- nickpsecurity 10y agoBetween you and ori_b, it sounds like proponents of undefined behavior optimization should distinguish between better optimization that's correct and possibly incorrect. I don't care how much faster it will go if it breaks my program or corrupts my data in subtle ways. However, if I didn't care for specific computations, then it would be good to know there were such optimizations available.
- ori_b 10y agoThis isn't about undefined behavior. It's about ignoring the way that floating point math works like real numbers. That lets you assume things like addition are commutative, which enables things like loop invariant code motion, reordering of operations, and generally doing
- 10y ago
- fao_ 10y agoNo compiler-performed optimization will make your computer run faster, unless it's software that pokes magic variables in the hardware. UB isn't exclusively for performance reasons. Some UB, like aliasing-related UB, is simply because there is no Right Way to do things (The standard does not define memory layout).
- cjhanks 10y agoInstructions: 1. Install Gentoo. 2. Compile with global optimization flags on for a week. 3. Compile with global optimization flags off for a week. 4. Decide. Unless you're doing numerical work (encoding/decoding/3D geometry/computer vision/...), you probably won't notice. And some desktop applications which used to work, might not work right anymore.
- CJefferson 10y agoNo, that's not the right check at all. The majority of those optimizations aren't taking advantage of undefined behaviour. Neither GCC nor clang provide a simple way of getting "no undefined behaviour" optimisations. Unfortunately, in practice it's often hard to define what that would actually mean. For example, fairly simple optimiations like optimising: int silly(int i) { int y = 3; int x[4]; x[i] = 4; return y; } To just: return 3; Technically relies on undefined behaviour -- if you compile this without optimisation then on my machine passing silly(7) returns 4 (as x[7] happens to write over y). So the question becomes, where is the "line" we want to draw on not allowing undefined behaviour optimisations? It turns out unfortunately in practice everyone seems to have a different line on what should be allowed.
- gpm 10y agoOverflow checks. Passing silly[7] should do something predictable, i.e. abort the program. This is, for example, what rust does. Of course studies have been done on how expensive overflow checking is. IIRC around 5% overhead in the most extreme examples.
- millstone 10y agoThis is an interesting example. The store to x is dead and ought to be totally elided, but Rust will still emit an "overflow check" for an array that does not exist. This overflow check dominates the cost of the function. If the optimizer determines a store is dead and can elide it, should it also elide the overflow checks? If "no," then it seems we've unnecessarily hamstrung the optimizer. If "yes," then whether a program panics is optimization-level dependent.
- twoodfin 10y agoI guarantee that if your compiler had to assume that pointers of different types could alias with defined behavior, you'd notice.
- DannyBee 10y agoErrr. It's been done before. Search the gcc mailing list archives, etc. So i'm not sure what you are waiting for. In fact, this type of thing has probably been done about 15-20 times in the past at least that i've seen. Someone always brings this up. Someone eventually bothers to run numbers, and it's very consistent that for icc, xlc, gcc, llvm, etc, you gain significantly in what you can do with loops and conditionals, as well as pointer analysis. Personally, as a pointer analysis maintainer, TBAA buys, on average, 10-20% precision. There is even a paper in a conference from intel that has the breakdown of where they get precision gains from various parts of aliasing disambiguation.
- maxlybbert 10y agoAssuming you meant "I'm waiting to see an A:B test that shows compiler optimizations that assume there is no undefined behavior in the program being compiled lead to a binary that runs faster" or something similar: each time somebody adds any kind of optimization to a compiler, they have to first check that the optimization actually leads to a faster binary. I'm not aware of any good way to request "all optimizations except the ones that rely on undefined behavior," so it would be very difficult to get this kind of test. But it's also true that whenever somebody files a bug against a compiler because the compiler did something unexpected when the programmer triggered undefined behavior (e.g., expected signed integer arithmetic to wrap, dereferenced a null pointer, got aliasing rules wrong, etc.) the compiler team is able to quickly point out the the performance gain from that particular optimization (e.g., "having signed integer overflow undefined means that tight loops run up to 20% faster").
- Ace17 10y agoI don't get it. AFAIK the goal of optimizers is to generate faster code while preserving the initial visible behaviour. If the initial behaviour is undefined, what can an optimizer try to preserve? Could someone give an example on how it would be possible not to have "UB in the compiler", while still having optimizations?
- aqjune 10y agoCompiler's spec is that the behavior of compiled program must be one of the behavior of source program, which is called 'refinement'.