-
Notifications
You must be signed in to change notification settings - Fork 377
remap function included in the std library #1899
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
Comments
That's a good idea, I will do so. |
If this helps anybody who wants to work on this, quite a bit before this issue was even filed, I had made the following note ot myself elsewhere: We already have the standard function
the inverse also seems useful:
and with that ingredient, we also can easily make
which remaps x's relative placement between a and b to the analogous proportionate position between c and d. |
Random comment but mix is better implemented for performance reasons as: Which keeps everything in registers and avoids the need to load the 1.f from memory, which can make quite a difference. Also, again, for performance reasons, the mix unmix version uses 7 ops whereas the version emklla suggests above uses 6, so whilst seemingly more verbose, I would expect the expanded version to execute faster, since the optimizer won't be able to remove the redundant op I think. |
We intentionally trade a little performance (maybe? see below) for numerical stability. The problem with I'm skeptical about performance claims here for two reasons: First, yes, looking at that one expression in complete isolation, that 1.0 needs to come from somewhere -- memory, if this is the only statement you are considering. But if it's near any other math that involves a 1.0, that value may already be in a register, so the cost can be amortized across multiple mix or other operations. Second, don't forget that we are doing really aggressive runtime optimization before lowering to LLVM IR. If any of a, b, or x can be identified as having known values at that point (which is common, and includes the case of any of them being non-interpolated parameters of the shader), the expression may get simplified or even optimized away entirely. (Also, turning any of those values into constants just puts us into the same pickle of having constant values that need to be loaded from somewhere.) So the idea of exactly what assembly the mix will turn into and what might be in registers is really squirrelly when you're talking about OSL source code and don't know the parameter values yet. |
That's all good points, I don't disagree with any of it. And yes, subtractive cancellation is a real pain. But I've definitely experienced better performance in the real-world (where the end point didn't matter, as they do here, I agree), but certainly not in the context of a JIT'ed shader, where yes, absolutely, there is the global optimization step that's quite different to comparison to an inlined C++ function, and that 1 has a higher change of existing elsewhere to be re-used, especially if it ends up in cache. But the mix unmix case still uses 1 more op, in theory, than the explicit remap implementation. |
Could be. I don't have a strong feeling about the specific implementation of remap. Mostly I had just jotted down in my notes that there's an elegant way to implement remap from a mix of an unmix. |
Sorry, I didn't mean to close and re-open this, just had the cursor in the wrong place at the moment I accidentally pushed on the trackpad. |
This formulation avoids needing to load the |
Fascinating, thanks. |
The need for a remap() function (also called efit() in VEX) is very common in shading, and it would be appreciated if the standard library included it natively.
So far, of course, we can remap vectors or floats by simply defining the function manually:
But, having it part of the std would simplify code and ensure a proper implementation:
The text was updated successfully, but these errors were encountered: