Live data from Hacker News

Your code is fast if you're lucky

tiki.li

51–60 of 90 posts

Re: Your code is fast if you're lucky

#51
post #40

Does anyone know exactly what is going on here to cause this difference? I am extremely puzzled that the "beginner friendly" code is not at some point in the compilation pipeline in EXACTLY the same representation as the non-"beginner friendly" code. I would imagine they'd be in the same form very early on, perhaps even at the point of generating an initial syntax tree. And once they take on the same form in the comp…

Representing code in a compiler is not precisely trivial, and the two statements are actually quite different from a compiler or AST perspective. Just looking at the first branch: *lwr = x; lwr++; This could be be represented with something like this (and this is a very vague approximation of an AST): block statement (assignment) expression operator (dereference) variable expression variable statement expression oper…

  block
    statement (assignment)
      expression
        operator (post-increment)
          operator (dereference)
            variable
      expression
        variable
I don't think this could possibly be a valid AST for '*lwr++ = x' because the increment is not an operation on the dereferenced value, its an operation on the pointer. So in this case I don't see how it could help but be transformed into a form similar to the "beginner friendly" case.

Or perhaps I am wrong and it would generate an AST like you describe and rely on later passes to actually create a proper dependency graph. My mental model of how these kinds of postfix operators work always assumed it must very early on turn it into two separate statements. Thank you for the suggestions.

Re: Your code is fast if you're lucky

#52
post #13
post #2

I really envy programmers who are so skilled at this kind of low-level optimization. The same meaning, but different performance based on notation—it's ultimately about entering LLVM's optimization pass, which likely comes down to differences in the internal IR pattern. It almost feels like a difference in innate talent... I feel like I can build CRUD applications well enough, but I still seem to be weak at low-level…

You could read compiler books, but I would actually recommend reading about CPUs and computer architecture directly. If you understand how the hardware works, then the optimizations are all very natural and fit into the picture perfectly, instead of being some arcane compiler magic that you have to take as a disconnected fact. Personally I actually haven't read too many books on optimizations, I just absorbed informa…

Thee optimization in question here was not obvious at all. It's a bs clang codegen quirk

Re: Your code is fast if you're lucky

#54
post #2

I really envy programmers who are so skilled at this kind of low-level optimization. The same meaning, but different performance based on notation—it's ultimately about entering LLVM's optimization pass, which likely comes down to differences in the internal IR pattern. It almost feels like a difference in innate talent... I feel like I can build CRUD applications well enough, but I still seem to be weak at low-level…

In order of priority, I’d say:

1. If you write CRUD apps, make sure that the database does the heavy lifting.

2. Take note of algorithm complexities, use hashtables as appropriate, and write good hash functions when you start using hashtables/dictionaries.

3. Avoid pointer-heavy datastructures. In high level languages like Java, an object reference is a pointer dereference that can stall the CPU waiting for memory. This is sometimes optimized, but you can’t depend on it. The true zealots call this “data oriented design”.

4. If you write C/C++,rust, or the like, you might want to learn to read assembly. Godbolt.com is a fun way to learn. Note that not all instructions are equally fast: Long division and trigonomic functions are slower than integer adds, even when they are both a single instruction.

5. The next level is probably going for vectorized instructions: SIMD (ARM Neon, AVX). The most original applications can be found at lemire.me: a professor exploring optimizing things like JSON parsing using the latest processor features.

Re: Your code is fast if you're lucky

#55
post #42

Don't forget to disable all "spectre and friends" mitigations in your linux kernel, and some workloads will become much faster. Can you do the same on the windows kernel or apple kernels?

Interesting, did not know you could do that but it does make sense. Make sure it’s air gapped.

https://wiki.archlinux.org/title/Improving_performance#Turn_...

Arch wiki says its okay.

Re: Your code is fast if you're lucky

#56

else *rwr-- = x; No. Make that obvious and the PR can pass. Argue, and you're off the project.

Fine. I'll use inline asm then.

I sometimes wonder whether that's a better idea for these micro-optimizations, rather than looking at the assembly code and trying to coax the compiler into generating what you want.

That said, I'm not keen on "argue and you're off the project" work environment.

Re: Your code is fast if you're lucky

#57
post #2

I really envy programmers who are so skilled at this kind of low-level optimization. The same meaning, but different performance based on notation—it's ultimately about entering LLVM's optimization pass, which likely comes down to differences in the internal IR pattern. It almost feels like a difference in innate talent... I feel like I can build CRUD applications well enough, but I still seem to be weak at low-level…

I don't have a book, but my best recommendation would be: Learn how to measure. Whatever language you are using should have a profiler. Learn how to use it and look at how your code holds up. Look for surprises; those are optimization opportunities and learning opportunities. Make a change that you think has a reasonable shot at optimizing performance, look at how the profile and benchmarks change. If you're using a compiled language, look at what the generated code looks like. Is it what you'd expect, or did the compiler do something that blindsided you? Can you get rid of that overhead? Can you use a faster algorithm? Can you make things faster without making it an unmaintainable mess?

In general, you must expect to try ten things and then one of them will help you; fewer if your ideas are bad. :-) Occasionally, you learn new things (either about your machine or your language or your code base) and then you can try that elsewhere in the code (but don't go overboard, every technique has its limits).

DO NOT FALL PREY TO SUPERSTITION. Always measure in one way or the other. Don't do stuff blindly just because someone on the Internet told you (there's a _lot_ of bad performance advice out there).

Re: Your code is fast if you're lucky

#60
post #40

Earlier quoted context omitted.

Representing code in a compiler is not precisely trivial, and the two statements are actually quite different from a compiler or AST perspective. Just looking at the first branch: *lwr = x; lwr++; This could be be represented with something like this (and this is a very vague approximation of an AST): block statement (assignment) expression operator (dereference) variable expression variable statement expression oper…

block statement (assignment) expression operator (post-increment) operator (dereference) variable expression variable I don't think this could possibly be a valid AST for '*lwr++ = x' because the increment is not an operation on the dereferenced value, its an operation on the pointer. So in this case I don't see how it could help but be transformed into a form similar to the "beginner friendly" case. Or perhaps I am…

Oops, you're right - I got the operators the wrong way around! I forget the precise precedence of * and ++ in C sometimes. Assuming that it would be bracketed as *(lwr++), it should actually be:

  block
    statement (assignment)
      expression
        operator (dereference)
          operator (post-increment)
            variable
      expression
        variable
Post reply on HN