logoalt Hacker News

spacecadet_yesterday at 5:24 PM1 replyview on HN

In the branchy function, id is only compared if distance is equal, and since distance is a random float, this almost never happens and the corresponding branch is nearly perfectly predicted. The branchless function always compares both id and distance, effectively doing twice the work. It's only part of the reason why there's a 2x performance difference, but I thought it was interesting.

I really don't know how LLVM picks between branches or conditional moves, but my guess is that it doesn't assume that float equality is any less likely than other conditions, and some optimization pass in O3 turns unpredictable branches into conditional moves. I base this on the fact that adding std::hint::unlikely to the "equal" branch produces the same assembly for the function in both modes.

https://godbolt.org/z/erGPKaPcx

Whether it's safe to assume in general that float equality is unlikely for the purpose of program optimization, I'll leave to the compiler engineers. If you know the data your program will be handling, adding hints will avoid these surprises.


Replies

charleslmungeryesterday at 5:53 PM

You can influence the choice of conditional moves (usually inserting them) with

__builtin_expect_with_probability(..., 0.5)

https://github.com/protocolbuffers/protobuf/commit/9f29f02a3...