Live data from Hacker News

Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

1f6042.blogspot.com

1–10 of 152 posts

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#4
Clang generates the shortest of these if you target sandybridge, or x86-64-v3, or later. The real article that's buried in this article is that compilers target k8-generic unless you tell them otherwise, and the features and cost model of opteron are obsolete.

Always specify your target.

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#5
post #3

Both recent GCC and Clang are able to generate the most optimal version for std::clamp() if you add something like -march=znver1, even at -O1 [0]. Interesting! [0] https://godbolt.org/z/YsMMo7Kjz

But then it uses AVX instructions. (You can replace -march=znver1 with just -mavx.)

When AVX isn’t enabled, the std::min + std::max example still uses fewer instructions. Looks like a random register allocation failure.

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#6
I'm a heavy std::clamp user, but I'm considering replacing it with min+max because of the uncertainty about what will happen when lo > hi. On windows it triggers an assertion, while other platforms just do a min+max in one or the other order. Of course, this should never happen but can be difficult to guarantee when the limits are derived from user inputs.

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#8
post #6

I'm a heavy std::clamp user, but I'm considering replacing it with min+max because of the uncertainty about what will happen when lo > hi. On windows it triggers an assertion, while other platforms just do a min+max in one or the other order. Of course, this should never happen but can be difficult to guarantee when the limits are derived from user inputs.

Pretty sure that their behaviors on NaN arguments will also differ.

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#9
post #3

Both recent GCC and Clang are able to generate the most optimal version for std::clamp() if you add something like -march=znver1, even at -O1 [0]. Interesting! [0] https://godbolt.org/z/YsMMo7Kjz

But then it uses AVX instructions. (You can replace -march=znver1 with just -mavx.) When AVX isn’t enabled, the std::min + std::max example still uses fewer instructions. Looks like a random register allocation failure.

The additional "movapd xmm0, xmm2" is mostly free as it is handled by renaming, but yes, it seems a quirk of the register allocator. It wouldn't be the first time I see GCC trying to move stuff around without obvious reasons.

Re: Std: Clamp generates less efficient assembly than std:min(max,std:max(min,v))

#10
On gcc 13, the difference in assembly between the min(max()) version and std::clamp is eliminated when I add the -ffast-math flag. I suspect that the two implementations handle one of the arguments being NaN a bit differently.

https://gcc.godbolt.org/z/fGaP6roe9

I see the same behavior on clang 17 as well

https://gcc.godbolt.org/z/6jvnoxWhb

Post reply on HN