Add float type and flag for nearest integer to automatically test with
and without SSE4.2 flag.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
libc/src/__support/FPUtil/nearest_integer.h | ||
---|---|---|
31 | Can you explain where this overload is to be used? I am asking because I see couple of problems here:
Going by #1 at least, I am surprised that this fallback implementation is serving as a drop-in-replacement to the x86_64 and aarch64 specializations. If a drop-in-replacement is in fact the intention, then the testing strategy should be this:
One more point that strikes me here is the comment you have above, "... in case of a tie, might pick a random one among 2 closest integers when the rounding mode is not FE_TONEAREST." If the users' algorithms are really tolerant to such "randomness", then perhaps we should give this fallback a name which captures that randomness aspect. Also, if there is only one user of this fallback, then may be this fallback should live with that user and not as utility? |
libc/src/__support/FPUtil/nearest_integer.h | ||
---|---|---|
31 | Thanks for spotting the data type issue! About the intention of the change, this is to be used for improving exp*f functions as experimenting in https://reviews.llvm.org/D130008. The main thing that these functions are used to to replace the idiom for rounding to nearest integer that we've been using: int k = static_cast<int>(x < 0 ? x - 0.5f : x + 0.5f); float kf = static_cast<float>(k); This by itself also has all the problems that you mentioned in the comment, such as FLT_EVAL_METHOD, possible different answers for different rounding modes, etc. Maybe I shouldn't use the word random. It well-defined, it's just too wordy to describe its behavior explicitly in all cases. About testing, this function is similar to fputil::multiply_add and fputil::polyeval that might give slightly different answers with/without special instructions, and that the fallback path is never taken on aarch64. So it's suitable for a flag control in the same way:
So to answer to your questions: this function is kind of similar to polyeval / multiply_add, and will be used by several functions, hence being shared here. |
libc/src/__support/FPUtil/nearest_integer.h | ||
---|---|---|
31 |
For my knowledge, can you explain what the problem is with this idiom and how the proposed implementation is solving it?
Considering that this fallback is not equivalent to the behavior of the native instructions, and that it was previously erroneous for some inputs, can I conclude that exp*f you are experimenting with is tolerant to such incorrectness?
|
libc/src/__support/FPUtil/nearest_integer.h | ||
---|---|---|
31 |
This idiom first converting a floating point type to an integer type, and then converting back to a floating point. CPUs seem to hate this ping pong back and forth between floating point and integer registers, significantly reduce the throughput and increase latency with its on the critical path, which is mostly floating point computations. The key point that makes this implementation improves the performance is that the entire computation is within floating point type and not too many branches.
Yes, it can kind of tolerate these different inputs (I wouldn't call it incorrect, since technically they are all correct, just different decisions / rounding modes when there is a tie), probably few exceptional values need to be updated similar to sinf. |
Can you explain where this overload is to be used? I am asking because I see couple of problems here:
Going by #1 at least, I am surprised that this fallback implementation is serving as a drop-in-replacement to the x86_64 and aarch64 specializations. If a drop-in-replacement is in fact the intention, then the testing strategy should be this:
One more point that strikes me here is the comment you have above, "... in case of a tie, might pick a random one among 2 closest integers when the rounding mode is not FE_TONEAREST." If the users' algorithms are really tolerant to such "randomness", then perhaps we should give this fallback a name which captures that randomness aspect. Also, if there is only one user of this fallback, then may be this fallback should live with that user and not as utility?