Comment by purplesyringa
1 day ago
> the fence basically means "resolve all funny business with this variable before proceeding"
Thanks, that's a good explanation! I understand it better now.
> What I'd actually worry most about is poisoning the prefetchers, and speculation more generally.
I didn't know prefetchers rely on address generation instructions, I thought they only tracked accessed memory. Good to know! Do you know any relevant external resources about this, by any chance?
I don't have anything covering recent generations. Try the usual suspects, I guess (Agner Fog et al). Sorry that's not more useful, but I haven't seriously worked on x86 in over a decade, so I'm a bit out of date.
Certainly, back then the prefetchers were a lot happier when they could easily identify patterns. They are more sophisticated now, but the old tricks still work. Avoiding register-based indirection is a major help to pretty much everything. When the base register gets updated, as well as the index register, that's hard to optimize. It shows up in both memory prefetch as well as speculation past an instruction.
The other idea to keep in your head is to start thinking in SSA form. Compilers live and breath SSA, so if your fast-path code looks like SSA with a couple of phi nodes, well, it's probably going to generate like you think it will. That's why I preferred the explicit `update_j` style: it's SSA form!