Comment by patrulek
2 days ago
You can utilize MLP (memory-level parallelism) and reduce memory latency by reading whole 8 bytes of next_j at every iteration. Just do something like
`uint64_t packed_next_j = *(uint64_t*)(&next_j[i])`
and then just shift right to find proper j. This way you remove dependency on previous iteration. Did you tried that?
The right-shift is the problem. You need to shift right by `j * 8`, which itself requires a shift to compute (`j << 3`), so you have two shifts on the critical path, resulting in a latency of 2 cycles. It's better than a load, but it's still noticeable.
2 cycles vs ~5 cycles is still nice improvement plus its more deterministic (but not that fast in optimistic case; better in pessimistic case) than `if` appraoch and probably easier to "invent" and reason about. Definitely not that cool as your `if` solution though :)
Don't you need the previous iteration to find out how much you need to shift right?
Yes you need, but the initial problem here were sequential loads from L1 into registers.