-
-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add safe acos and safe asin #76876
Closed
Closed
Add safe acos and safe asin #76876
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand the intent to have both an explicit
safe_asin
and the mainasin
which is safe by default, but having two synonymous methods just means that we'll introduce inconsistency across the codebase where some contributors useasin
and others usesafe_asin
.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a tricky one. I added the explicit
safe_acos
to replace parts of code that were already clamping. This signifies areas where the author / bugfix has shown clamping to be absolutely necessary.In general there are three cases rather than two:
safe_acos
)acos
)unsafe_acos
)We could alternatively use a comment to specify that a clamp is necessary instead of
safe_acos
(1), but having all three is clear and easily searchable.I can adjust the PR to use comments to distinguish (1) and (2) but imo I would caution against it. What happens when you later come to optimize a function that uses
acos
? You now no longer know whether it must be safe or not (unless you re-analyse the code, which may be complex for math) - has someone missed a comment etc. There is essentially a danger of e.g. 10 different programmers examine the same bit of code in the following years and waste time trying to work out the intent again and again, when the code just could have been explicit from day 1.I can add some comment explanation to the
math_funcs.h
file to make it clearer when to use each version, as a guide for contributors. 🤔The other alternative which I may have mentioned earlier, is to disallow the generic
acos
and force all (core) use to be explicit. This is a compromise but you do lose a little information, but might be viable. We can't easily remove the generic to prevent compat breaking in modules etc.Anyway I am happy to modify the PR if broad opinion favours one of the other options, but just want to caution that "simplifying" potentially has a cost in terms of future maintenance / bug prevention. 🙂
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might benefit from some deeper analysis of the uses of the trigonometric functions, from the case in #8111 there might be reasons to use
atan2
instead in situations where it is possible, i.e. where a well defined x and y can be found, I think fixing the immediate problem of NaNs might be sufficient to merge this with a placeholder function and then investigate individual cases to follow upThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Not sure about real code) But at least in micro benchmarks the
unsafe
version is only about 0.5% faster then the branched version (if all inputs are actually in the -1 - 1 range, otherwise the branched version quickly wins), so I am not sure if the unsafe version of these functions is actually necessary at all.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RedworkDE that's actually a good point. The unsafe version by definition shouldn't be hitting the -1 / +1 limit. I guess we could do this. The other option is that the unsafe version is so rare (not even used as yet) that we could directly call
::acos
at the call site with a comment. 🤔(This is difficult to benchmark because the benchmark with that data will presumably be using perfect branch prediction, and in the real world it is more likely to be mixed instructions.)
The other option is to just use safe version everywhere, and delay this discussion until we actually find a case where profiling shows would benefit from the unsafe(!). 😄
I'll create another simpler PR with just the safe version and will let you guys decide which to go for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@RedworkDE comparing unsafe to the branching, I'm getting unsafe being around:
4% faster (when some are outside range)
10% faster (when all inside range)
This probably depends very much on the benchmark / CPU / compiler / compiler options etc. But in general the clamped version shouldn't be that much slower (and in practice, often cache is the bottleneck rather than these instructions).
Also, as ever, benchmarking is notoriously easy to get wrong 😄 , yours may be more reliable if you are using google benchmark, I'm doing this in a test app.