I'm a noob. Looking at the disasm: https://godbolt.org/z/766aPTPc3 It turns a CMOVQLT to a JLT. Is the blog saying CMOVQLT don't have branch predication? I don't get it.
Print(“lol”) doubled the speed of my Go function
11–20 of 130 posts
Re: Print(“lol”) doubled the speed of my Go function
#12Why is there a "continue" at all in the first code sample? Edit to add: does removing it make any difference?
https://godbolt.org/z/ds1raTYc9
https://godbolt.org/z/rbWsxM83b
The `print("lol")` output looks remarkably different.
Re: Print(“lol”) doubled the speed of my Go function
#13In the Linux kernel, there are unlikely() and likely() macros which indicate to the compiler whether or not a condition is likely using __builtin_expect (which then influences the output assembly into producing code that should make the branch predictor do the right thing more of the time). Unfortunately, the issue here is that the performance depends on the input and so such hints wouldn't help (unless you knew a-pr…
Re: Print(“lol”) doubled the speed of my Go function
#14Earlier quoted context omitted.
I'm in school, so this may be oversimplified, but if the processor/assembly code is predicting the next result, it gets the result faster. The processor only does this prediction with conditional branches. The extra if for printing or finding the min invoke the prediction with the accuracies stated.
> The processor only does this prediction with conditional branches This sounds... wrong? Unless ARM64 is designed in an absurd way? I'd love to see the full disassembly; something seems funny here. If it was x86 I would say it's a conditional move causing this, but I don't know what's going on on ARM.
I am confused by this behaviour, and although I definitely don't know what the answer is here; the non-lol version does have a CSEL (https://developer.arm.com/documentation/dui0802/b/CSEL) which is totally missing from the lol version.
Non-lol https://godbolt.org/z/ds1raTYc9
Re: Print(“lol”) doubled the speed of my Go function
#15I'm a noob. Looking at the disasm: https://godbolt.org/z/766aPTPc3 It turns a CMOVQLT to a JLT. Is the blog saying CMOVQLT don't have branch predication? I don't get it.
Your disasm is for x86-64. The benchmarks in the blog were run on an M1 MacBook Pro, which is an ARM64.
Re: Print(“lol”) doubled the speed of my Go function
#16Earlier quoted context omitted.
> The processor only does this prediction with conditional branches This sounds... wrong? Unless ARM64 is designed in an absurd way? I'd love to see the full disassembly; something seems funny here. If it was x86 I would say it's a conditional move causing this, but I don't know what's going on on ARM.
It's interesting that you say conditional move here. I am confused by this behaviour, and although I definitely don't know what the answer is here; the non-lol version does have a CSEL ( https://developer.arm.com/documentation/dui0802/b/CSEL ) which is totally missing from the lol version. Non-lol https://godbolt.org/z/ds1raTYc9 lol https://godbolt.org/z/c3afrb6bG
Re: Print(“lol”) doubled the speed of my Go function
#17Earlier quoted context omitted.
It's interesting that you say conditional move here. I am confused by this behaviour, and although I definitely don't know what the answer is here; the non-lol version does have a CSEL ( https://developer.arm.com/documentation/dui0802/b/CSEL ) which is totally missing from the lol version. Non-lol https://godbolt.org/z/ds1raTYc9 lol https://godbolt.org/z/c3afrb6bG
Ah there you go, that's the conditional move on ARM. Yeah, those are slow.
Hopefully someone with a deeper understanding can verify or discredit this here. I'm curious to see the fix for this (I assume it will generate a fix).
Re: Print(“lol”) doubled the speed of my Go function
#18Earlier quoted context omitted.
Your disasm is for x86-64. The benchmarks in the blog were run on an M1 MacBook Pro, which is an ARM64.
Sorry. My bad. But looking at ARM64 https://godbolt.org/z/YEjGKce1Y The difference is CSEL and BLT. The question still stands. Does CSEL have no branch predication?
"So far, we have seen examples that use branches to handle decisions. The A64 instruction set also provides conditional select instructions. In many cases, these instructions can be used as an alternative to branches."
Seems CSEL is not a branch.
Re: Print(“lol”) doubled the speed of my Go function
#19I read it and I still don't get it, can someone (re-)explain what the presence of the print() is doing that is helpful for branch prediction (or any other aspect of the CPU)? Update: It seems to be the conditional move, see https://news.ycombinator.com/item?id=37245325
Re: Print(“lol”) doubled the speed of my Go function
#20Earlier quoted context omitted.
Ah there you go, that's the conditional move on ARM. Yeah, those are slow.
Yeah, after reading the blog post I felt reasonably confident that this is a compiler bug (in terms of perf). Hopefully someone with a deeper understanding can verify or discredit this here. I'm curious to see the fix for this (I assume it will generate a fix).