Live data from Hacker News

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

1f6042.blogspot.com

31–40 of 152 posts

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

#31

Earlier quoted context omitted.

Ehh, not so much inaccurate, more of a "floating point numbers are tricky, let's act like they aren't". Compilers are pretty skittish about changing the order of floating point operations (for good reason) and ffast-math is the thing that lets them transform equations to try and generate faster code. IE, instead of doing "n / 10" doing "n * 0.1". The issue, of course, being that things like 0.1 can't be perfectly rep…

I've never understood why generating exceptions is preferable to just using higher precision.

Higher precision isn’t always available. IEEE 754 is an unusually well-thought-through standard (thanks to some smart people with a lot of painful experience) and is pretty good at justifying its decisions, some of which are surprising (far from obvious) to anyone not steeped in it.

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

#32
post #2

If you benchmark these, you'll likely find the version with the jump edges out the one with the conditional instruction in practice.

Compilers often under-generate conditional instructions. They implicitly assume (correctly) that most branches you write are 90/10 (ie very predictable), not 50/50. The branches that actually are 50/50 suffer from being treated as being 90/10.

The branches in this example are not 50/50.

Given a few million calls of clamp, most would be no-ops in practice. Modern CPUs are very good at dynamically observing this.

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

#33
post #21
post #18

Earlier quoted context omitted.

Yep. Adding "-C target-cpu=native" to rustc on my desktop computer consistently gets a ~10-15% performance boost compared to the default target. The default target is extremely conservative. As far as I can tell, it doesn't take advantage of any CPU features added in the last 20 years. (The k8 came out in 2003.)

Those Gentoo people were onto something.

Funny that it stopped being the case for a while around 2006. AMD64 became widespread while also being very new, closing the gap between "default" and "native".

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

#34
post #7
post #2

If you benchmark these, you'll likely find the version with the jump edges out the one with the conditional instruction in practice.

That must depend on the platform and the surrounding code, no?

Yes. On platform - most modern cpus are happier with predictable branches than exotic instructions.

On surrounding code - for sure.

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

#35
post #22

Earlier quoted context omitted.

> Of course, this should never happen but can be difficult to guarantee when the limits are derived from user inputs. Sounds to me like you are missing a validation step before calling your logic. When it comes to parsing, trusting user input is a recipe for disaster in the form of buffer overruns and potential exploits. As they used to say in the Soviet Union: "trust, but verify".

That was what Reagan said about the Soviet Union, not what was said in the Soviet Union. Correct me if I'm wrong.

According to wikipedia you're right (about Reagan) but it's also a Russion proverb.

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

#36
post #15
post #2

If you benchmark these, you'll likely find the version with the jump edges out the one with the conditional instruction in practice.

FYI. https://quick-bench.com/q/sK9t9GoFDRkx9XxloUUbB8Q3ht4 ' Using this microbenchmark on an Intel Sapphire Rapids CPU, compiled with march=k8 to get the older form, takes ~980ns, while compiling with march=native gives ~570ns. It's not at all clear that the imperfection the article describes is really relevant in context, because the compiler transforms this function into something quite different.

With random test cases, branch prediction can't help.

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

#37
post #11

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

You (celegans25) probably know this but here is a PSA that -ffast-math is really -finaccurate-math. The knowledgeable developer will know when to use it (almost never) while the naive user will have bugs.

Why do you say almost never? Don’t let the name scare you; all floating point math is inaccurate. Fast math is only slightly less accurate, I think typically it’s a 1 or maybe 2 LSB difference. At least in CUDA it is, and I think many (most?) people & situations can tolerate 22 bits of mantissa compared to 23, and many (most?) people/situations aren’t paying attention to inf/nan/exception issues at all.

I deal with a lot of floating point professionally day to day, and I use fast math all the time, since the tradeoff for higher performance and the relatively small loss of accuracy are acceptable. Maybe the biggest issue I run into is lack of denorms with CUDA fast-math, and it’s pretty rare for me to care about numbers smaller than 10^-38. Heck, I’d say I can tolerate 8 or 16 bits of mantissa most of the time, and fast-math floats are way more accurate than that. And we know a lot of neural network training these days can tolerate less than 8 bits of mantissa.

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

#38
post #22

Earlier quoted context omitted.

> Of course, this should never happen but can be difficult to guarantee when the limits are derived from user inputs. Sounds to me like you are missing a validation step before calling your logic. When it comes to parsing, trusting user input is a recipe for disaster in the form of buffer overruns and potential exploits. As they used to say in the Soviet Union: "trust, but verify".

That was what Reagan said about the Soviet Union, not what was said in the Soviet Union. Correct me if I'm wrong.

https://en.wikipedia.org/wiki/Trust,_but_verify

> Trust, but verify (Russian: доверяй, но проверяй, tr. doveryay, no proveryay, IPA: [dəvʲɪˈrʲæj no prəvʲɪˈrʲæj]) is a Russian proverb, which is rhyming in Russian. The phrase became internationally known in English after Suzanne Massie, a scholar of Russian history, taught it to Ronald Reagan, then president of the United States, the latter of whom used it on several occasions in the context of nuclear disarmament discussions with the Soviet Union.

Memorably referenced in "Chernobyl": https://youtu.be/9Ebah_QdBnI?t=79

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

#39
post #22

Earlier quoted context omitted.

> Of course, this should never happen but can be difficult to guarantee when the limits are derived from user inputs. Sounds to me like you are missing a validation step before calling your logic. When it comes to parsing, trusting user input is a recipe for disaster in the form of buffer overruns and potential exploits. As they used to say in the Soviet Union: "trust, but verify".

That was what Reagan said about the Soviet Union, not what was said in the Soviet Union. Correct me if I'm wrong.

[deleted]

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

#40
post #22

Earlier quoted context omitted.

> Of course, this should never happen but can be difficult to guarantee when the limits are derived from user inputs. Sounds to me like you are missing a validation step before calling your logic. When it comes to parsing, trusting user input is a recipe for disaster in the form of buffer overruns and potential exploits. As they used to say in the Soviet Union: "trust, but verify".

That was what Reagan said about the Soviet Union, not what was said in the Soviet Union. Correct me if I'm wrong.

Russian here. We use that expression from time to time: https://ya.ru/search/?text="доверяй%2C+но+проверяй"
Post reply on HN