←back to thread

386 points ingve | 3 comments | | HN request time: 0.451s | source
Show context
pizza234 ◴[] No.35738299[source]
Some information on the CMOV can be found on the Intel Optimization Reference Manual (https://cdrdv2-public.intel.com/671488/248966-046A-software-...).

Torvalds was famously critical of it (https://yarchive.net/comp/linux/cmov.html); part of the criticism is now moot though, due to low latencies on modern processors (it seems 1 cycle or less, although the instruction consumes internal flags).

His idea seems to be still applicable and consistent with Intel's recommendation: make branches predictable, and only after, use CMOV for the remaining ones. His fundametnal assumption is that "even if you were to know that something is unpredictable, it's going to be very rare.".

replies(3): >>35738345 #>>35741256 #>>35742105 #
2102922286 ◴[] No.35738345[source]
This is one area where Profile-Guided Optimization (PGO) can help a lot! With PGO, you run your program on some sample input and it logs info like how many times each side of a branch was taken. From there, you can recompile your code. If the compiler sees that one side of the branch dominates, it can emit code to prioritize that branch. However if the branch counts are approximately even and the branch is hard to predict (n.b. this is technically distinct from having even branch counts), then the compiler can know that the CPU would have trouble predicting the branch, and can emit a cmov instruction instead.
replies(4): >>35738413 #>>35739365 #>>35740748 #>>35745104 #
berkut ◴[] No.35738413[source]
Yeah, it's mildly annoying there's no (at least to my knowledge?) compiler hint like the '__builtin_expect' ones to tell compilers that the values are very unlikely going to be predictable with enough accuracy to allow the branch predictors to be useful in general, and to use a cmov instead of the traditional branching instructions because of this.
replies(2): >>35738478 #>>35739092 #
1. dist1ll ◴[] No.35738478[source]
clang has __builtin_unpredictable [0]

[0] https://clang.llvm.org/docs/LanguageExtensions.html#builtin-...

replies(2): >>35738484 #>>35747016 #
2. berkut ◴[] No.35738484[source]
Oooooh :)

Thanks!

3. usefulcat ◴[] No.35747016[source]
It does, but unfortunately it doesn't always work. For example (note the -march=broadwell option):

https://godbolt.org/z/n1Kz4G7GE