Live data from Hacker News

You can't fool the optimizer

xania.org

141–150 of 193 posts

Re: You can't fool the optimizer

#141
I'm not well-versed in compilers, so it was a bit surprising to see how it optimizes all the add_vX functions.

What I most enjoyed, though, was how the guy in the video (linked at the bottom of the article) was typing - a mistake on every few characters. Backspace was likely his most-used key. I found it encouraging, somehow. I know typing speed or correctness isn't really important for coders, but I always felt like I'm behind others with regards to typing, even though when I really concentrate, I do good on those online typing tests. Even when writing this comment, I made like 30 mistakes. Probably an useless comment, but it may give some people hope or validation if they feel like they not great typists.

Re: You can't fool the optimizer

#142
post #60

This post assumes C/C++ style business logic code. Anything HPC will benefit from thinking about how things map onto hardware (or, in case of SQL, onto data structures). I think way too few people use profilers. If your code is slow, profiling is the first tool you should reach for. Unfortunately, the state of profiling tools outside of NSight and Visual Studio (non-Code) is pretty disappointing.

I don’t disagree, but profiling also won’t help you with death by a thousand indirections.

Sure, but that's mostly a myth.

Re: You can't fool the optimizer

#143
post #117

Earlier quoted context omitted.

`s` may be null, and so the strlen may seg fault.

Since the optimiser is allowed to assume you're not invoking UB, and strlen of null is UB, I don't believe that it would consider that case when optimising this function.

I understand that, but I don't agree that such optimizer behavior is worth it and I won't put it in my compilers.

Re: You can't fool the optimizer

#144

The examples are fun, but rather than yet another article saying how amazing optimizing compilers are (they are, I already know), I'd probably benefit more from an article explaining when obvious optimizations are missed and what to do about it. Some boring examples I've just thought of... eg 1: int bar(int num) { return num / 2; } Doesn't get optimized to a single shift right, because the that won't work if num is n…

> int bar(int num) { return num / 2; } > > Doesn't get optimized to a single shift right, because the that won't work if num is negative. Nit: some might think the reason this doesn't work is because the shift would "move" the sign bit, but actually arithmetic shifting instructions exist for this exact purpose. The reason they are not enough is because shifting provides the wrong kind of division rounding for negativ…

Will shift, shift, and add be slower or faster than a divide instruction on machines with a divide instruction?

Re: You can't fool the optimizer

#145

Earlier quoted context omitted.

No, the compiler may assume that the behavior of standard library functions is standards-conformant.

> No, the compiler may assume that the behavior of standard library functions is standards-conformant. Why? What happens if it isn't?

The most common reason is to do optimizations such as replacing strlen("hello") with 5 or open-coding strlen (or, more commonly, memcpy or memcmp). If you're linking with a non-conformant strlen (or memcpy or whatever) the usual thing that happens is that you get standards-compliant behavior when the compiler optimizes away the call, but you get the non-conformant behavior you presumably wanted when the compiler compiles a call to your non-conformant function.

But the orthodox answer to such questions is that demons fly out of your nose.

Re: You can't fool the optimizer

#146
post #97

Earlier quoted context omitted.

eg 4: int foo(char const *s) { if (s[0] == 'h' && s[1] == 'e' && s[2] == 'l' && s[3] == 'l') return 1; return 0; } The outputs 4 cmp instructions here, even though I'd have thought 1 was sufficient. https://godbolt.org/z/hqMnbrnKe

`s[0] == 'h'` isn't sufficient to guarantee that `s[3]` can be access without a segfault, so the compiler is not allowed to perform this optimization. If you use `&` instead of `&&` (so that all array elements are accessed unconditionally), the optimization will happen: https://godbolt.org/z/KjdT16Kfb (also note you got the endianness wrong in your hand-optimized version)

This is fantastic, thanks! This is the approach I use in httpdito to detect the CRLFCRLF that terminates an HTTP/1.0 GET request, but I'm doing it in assembly.

Re: You can't fool the optimizer

#147
post #117

Earlier quoted context omitted.

Since the optimiser is allowed to assume you're not invoking UB, and strlen of null is UB, I don't believe that it would consider that case when optimising this function.

I understand that, but I don't agree that such optimizer behavior is worth it and I won't put it in my compilers.

I appreciate that greatly.

Re: You can't fool the optimizer

#148

I always code with the mindset “the compiler is smarter than me.” No need to twist my logic around attempting to squeeze performance out of the processor - write something understandable to humans, let the computer do what computers do.

> I always code with the mindset “the compiler is smarter than me.”

That mindset will last until the first or second time you walk through the compiler's assembly-language output. GCC and LLVM can find some amazing optimizations, but they also consistently miss very obvious optimization opportunities, often even on utterly trivial code.

That isn't to say that it's worthwhile to hand-optimize all your code. But the compiler is very much not smarter than you, and if you do need to squeeze performance out of the processor, you can do a lot better than the compiler does. A good first step is to look at the stupid shit the compiler has spat out and massage your source code until the shit stinks less.

Re: You can't fool the optimizer

#150

Wait, why does GAS use Intel syntax for ARM instead of AT&T? Or something that looks very much like it: the destination is the first operand, not the last, and there is no "%" prefix for the register names?

That's not Intel syntax that's more or less ARM assembly syntax as used by ARM documentation. Intel vs AT&T discussion is primarily relevant only for x86 and x86_64 assembly. If you look at GAS manual https://ftp.gnu.org/old-gnu/Manuals/gas-2.9.1/html_chapter/a... almost every other architecture has architecture specific syntax notes, in many cases for something as trivial comments. If they couldn't even decide on si…

As I understand it, GCC and gas for i386 were written to be compatible with existing Unix C compilers (emitting assembly) and assemblers (consuming assembly), and those tools used the "AT&T" syntax that copied the PDP-11 assembler's syntax.

For amd64 there isn't really much of an excuse. Intel syntax was already supported in gas.

Post reply on HN