83 pointsby birdculture6 hours ago7 comments
  • throawayonthe3 hours ago
    lobsters comment points out [[unlikely]] works here for clang

    https://clang.godbolt.org/z/r4xYWfPfe

    edit: oh the article also mentions it now :)

  • mcv4 hours ago
    Interesting. I thought modern CPU optimisation required avoiding branches, but here adding the branch allows the branch pediction to parallelise what it otherwise couldn't.
    • zipy1243 hours ago
      It does and the key here is that adding the if is akin to avoiding a branch, since getting data then doing something with it is a hidden branch if you already have the data. All this code does is formalise the hidden branch so that it can be avoided when possible.
      • summarybotan hour ago
        That's pretty cool. Is there something obcluding the compiler from noticing this parallelization opportunity without the new `if` ?

        My understanding is the assignment and the evaluation are somehow coupled in this case based on the essay, but I could use an explanation.

        • purplesyringaan hour ago
          The optimization in the post is only advantageous if `next_j[i][j] == j` holds often enough. Without prior knowledge, the compiler can't know if it's going to improve performance, and the worst losses are greater than the best wins (branch misprediction is very expensive), so it decides not to interfere.
  • anematode6 hours ago
    Brilliant! Hadn't seen this technique before.
  • anthonj4 hours ago
    I think this call for something similar to "__builtin_expect" or linux' likely()/unlikely().

    Not very clean, but better than inserting obscure optimisations in the source.

    • gblargg4 hours ago
      Assuming compilers are smart enough to insert an unnecessary branch to break the dependency.
      • vitally3643an hour ago
        That's what the hints are for. Expect/likely/unlikely are the programmer informing the compiler what it should expect and how it should optimize
    • purplesyringa4 hours ago
      That would be great, if only it worked as intended! From the perspective of an optimizing compiler, `a == b ? a : b` is worse than `b` regardless of the probability you assign to `a == b`.

      ETA: someone on Lobsters (https://lobste.rs/s/1an425/quadrupling_code_performance_with...) noticed that `[[unlikely]]` actually works on LLVM (not on GCC, and with worse codegen on LLVM, but it's still good to know) -- updated the post.

    • MaxBarraclough4 hours ago
      I was wondering the same thing. Also, could profile-guided optimisation help here?
  • anirudhak475 hours ago
    latency optimization is a skill. I liked how you went till CSE pass. I myself wrote several passes to go to lowest latency possible
  • akoboldfrying5 hours ago
    This is really surprising! I've never considered the possibility that using an equality test to skip a write that would be a no-op could break a dependency and thus lead to higher perf overall if the "equal" outcome occurs often enough. This might be applicable in many situations where you "edit" some data in-place, but most of the time there are few or no changes.
  • 65103 hours ago
    my js brain keeps thinking encoding[i] = next_j[i][j];