20 ms·
I haven't got the time to read the paper yet but I believe I'd emerge with the more or less the same opinion that I've had before: nobody's forcing you to pass
by foxfluff 5y ago
I haven't got the time to read the paper yet but I believe I'd emerge with the more or less the same opinion that I've had before: nobody's forcing you to pass -O2 or -O3. It's stupid to ask the compiler to optimize and then whine that it optimizes. I usually am OK with the compiler optimizing, hence I ask it to do so. I'm glad that others who disagree can selectively enable or disable only the optimizations they're concerned about. Most of the optimizations that people whine about seem quite sane to me. Of course, sometimes you find real bugs in the optimizer (yesterday someone on libera/#c posted a snippet where gcc with -O2 (-fdelete-null-pointer-checks) removes completely legit checks)
- phicoh 5y agoIt seems to me a flaw in a language and in a compiler if the average programmer has to avoid higher levels of optimizating because it cannot be predicted what they do.
- Wowfunhappy 5y agoWhat if the only languages/compilers without that "flaw" had similar performance to lower optimization levels? (I don't know if that's the case, but it's what I thought the GP was implying.)
- phicoh 5y agoThere is a saying that you can make any program run fast if you don't care about correctness. We have reached the point where C programmers cannot understand the language/compiler anymore. Given that this has been going on for a long time, my hope is that Rust will be the next systems programming language.
- foxfluff 5y agoDo you think people understand Rust?
- phicoh 5y agoRust can be hard to write, but by and large is not hard to read. Rust does have more abstraction mechanisms than C. So it is possible to go overboard in that area. But that is more a coding style issue. C programs that nest multiple levels of functions pointers can also be hard to understand.
- pornel 5y agoThe safe subset of Rust does not permit any UB. This greatly simplifies understanding of UB in the majority of the codebase — because there isn't any. Only when there's an `unsafe` keyword in Rust, you put your "C" hat on. (it was and continues to be a challenge to uphold this guarantee, because UB in LLVM is so ubiquitous, e.g. Rust had to patch up float to int conversions and eliminate no-op loops)
- duped 5y agoIt's easier to understand production Rust than production C
- cma 5y agoRust code in unsafe blocks has lots of similar issues with fuzziness around aliasing rules: https://github.com/rust-lang/unsafe-code-guidelines/blob/master/active_discussion/aliasing.md https://github.com/rust-lang/unsafe-code-guidelines/blob/mas...
- couchand 5y agoIt doesn't seem like anyone is taking the position here that C is flawless. Rather, the question is, given both its flaws and its ubitquity, is it acceptable to trade off developer head-wall interactions for the possibility of high performance. The only winning move is not to play. (with C)
- foxfluff 5y agoI don't see it that way. Isn't that precisely the point of higher levels? Don't go there if you don't know what you're doing. Since we can't magically install knowledge into average programmer's heads, the only other choice would be to have those higher levels not exist because the average programmer will never understand them, and also the compiler can't mind-read the average programmer to understand that what they want isn't exactly what they said they want.
- fennecfoxen 5y agoI think the general problem is that if so much is going to hinge on this, it should be much easier to tell whether or not you know what you're doing. Undefined behavior really wouldn't be a problem if you could spot it reliably (possibly using tools, like the compiler toolchain itself). This loose mapping between four optimization levels and a variety of obscure language situations is invisible and situated only in a handful of top engineers' memories. That's not a great way to run a language if you actually care about the correctness of programs written in that language.
- immibis 5y agoI always thought the main point of the levels was simply compilation speed. That and debuggability.
- gpderetta 5y agoFor the most part yes. O3 also enables (or used to) some optimizations that are not always profitable.
- wongarsu 5y ago> Isn't that precisely the point of higher levels? I used to think that higher levels are for giving the compiler more time to think so it can come up with a better result (and for somewhat specifying the desired space-performance tradeoff). In my mind the "don't do it if you don't know what you are doing"-things were seperate flags, like -ffast-math. Obviously I eventually learned that bad things can happen, but "just build prod with -O2" still seems to be what almost everyone does.
- maxlybbert 5y agoI’m amused by the people who ask for optimization and then complain about it. Or the “it did what I said, not what I meant” crowd. But, officially, undefined behavior is always undefined, not just at higher optimization levels.
- vgatherps 5y agoThis is a pretty dismissive response to something that's a real problem. Sure, the "Why are you deleting my checks for if *this is null" is a little silly - but there are definitely sharp edges where UB conflicts with actually useful things you might want to do. Did you know seqlocks are undefined (benign race conditions)? Ever ran into padding concerns playing poorly with trying to do atomic CAS? It's not unreasonable for the standard to say 'padding is undefined', 'data-races are undefined' - but having no way to say "hey, trust me, please un-poison this thing you don't like" is pretty unfortunate.
- jcranmer 5y ago> Did you know seqlocks are undefined (benign race conditions)? It wouldn't be undefined behavior if you used atomic variables--data races involving atomics aren't undefined behavior.
- vgatherps 5y agoThat is true in theory, but in practice it's not feasible. Even assuming you restrict to trivially copyable types, you either have to have a purely-atomic duplicate of anything that you want to store, or play games with trying to get a fast atomic memcpy. Unless things have changed a lot in the past two years neither LLVM or GCC do that much optimisation around atomics so this comes with disastrous performance implications as well as overhead battling the standard.
- gpderetta 5y agoYes, a fast and safe seqlock is still elusive. We will hopefully get the misleadingly named std::atomic_memccpy at some point in the future.
- marcosdumay 5y agoOptimizations aren't supposed to change the meaning of your code. And specifically for C, unsafe optimizations are supposed to only apply with -O3. Level 2 is supposed to be safe.
- foxfluff 5y ago> And specifically for C, unsafe optimizations are supposed to only apply with -O3. Level 2 is supposed to be safe. Citation needed? AIUI optimization levels are entirely up to the compiler. GCC's man page says nothing about the safety of these levels. > Optimizations aren't supposed to change the meaning of your code. And they generally won't. The trouble is when the meaning of your code wasn't well defined to begin with (or you thought it meant something it didn't).
- marcosdumay 5y ago> GCC's man page says nothing about the safety of these levels. Well, it used to.
- josephcsible 5y agoImagine you and the compiler are parties to a contract. Your obligation is to not let UB happen. The compiler's obligation is to not change the meaning of your code. Insisting that the compiler should uphold its end of the deal when you don't uphold yours is like saying if you sign a contract to buy widgets, you should have to pay even if the vendor fails to deliver them.
- marcosdumay 5y ago> Your obligation is to not let UB happen. Sorry, no can do. If that's the contract than C is a completely useless language.
- Filligree 5y ago> Sorry, no can do. If that's the contract than C is a completely useless language. That is the contract. Your inference may be correct, but it does no good to insist that C should behave differently than it does. There are better options.
- bcrl 5y agoAt least in compilers like gcc, optimization needs to be enabled to get sane warnings emitted by the compiler, so some people are indeed being forced to pass in -O2 to get sane build warnings for projects. I would really like it for the C standard to clean up Undefined Behaviour. Back in the 1980s when ANSI C was first specified, a lot of the optimizations that modern compiler writers try to justify via Undefined Behaviour simply weren't part of many compiler's repertoires, so most systems developers didn't need to worry about UD and there was no push for the standard to do so as a result. If people really want the optimizations afforded by things like assuming an int can't overflow to a negative number in a for loop, my personal position is that the code should be annotated such that the optimization is enabled. At the very least, the compiler should warn that it is making assumptions about potentially UB when applying such optimizations. There is this false belief that all legacy code should be able to compiled with a new compiler with no changes and expect improved performance. Anyone who works on real world large systems knows that you can't migrate to newer compilers or updated OSes with zero effort (especially if there's any C++ involved). I understand that compiler writers want to improve their performance on SPEC, but the real world suffers from the distortions caused by viewing optimizations through the narrow scope of benchmarks like SPEC.
- foxfluff 5y ago> At least in compilers like gcc, optimization needs to be enabled to get sane warnings emitted by the compiler, so some people are indeed being forced to pass in -O2 to get sane build warnings for projects. That's a fair point and it irritates me too. But you're not forced to run -O2 in production if you don't want to. I've had projects where we compile with multiple compilers and different settings -- including different libcs -- just to get all the warnings, while we ship non-optimized or minimally optimized debug builds to the customer..
- bcrl 5y agoYou can't turn off -O2 in some projects. The Linux kernel has plenty of code that requires optimization to be on to build succesfully -- look at things like BUILD_BUG_ON(). And it's projects like the Linux kernel that have had security issues caused by overzealous compiler optimizations. Getting blindsighted silently by compilers has already proven that the current approach towards Undefined Behaviour by compiler writers is not working.