我正在浏览代码库并找到以下模板函数:
template <class T, class T2>
T mix(const T &a, const T &b, const T2 &interp) {
static constexpr T2 one = ((T2)1);
return (a * (one - interp)) + (b * interp);
}
以下评论
// You'd think instead of doing the a*(1-t) + b*t, it'd be faster
// and one less multiply to do a + (b-a)*t, right? Bad! Increases floating
// point exception occurances. Same as LERP
有人可以强调为什么这应该是真的吗?
答案 0 :(得分:3)
正如Paul R在评论中所说的那样,评论可能是指非正规(我更常见的是将它们描述为次正规,因此将使用该术语)数字,这些数字在浮点算术中填充了零下的漏洞。
如果a
和b
的值足够接近,那么a-b
将产生一个次正常值。当这些值完全由硬件处理时,通常会有性能损失。有一些技术可以在硬件中减轻这种影响,但是,对于某些现代处理器,涉及次正规的指令可能比作用于正常值的相同指令花费的时间长100多倍。如果这些值完全由软件处理(例如,硬件指令不直接处理它们,并且引发浮点异常,必须捕获然后在软件中进行整理),实际上总是会降低性能。
根据应用程序的类型,由此产生的问题可能会有所不同(例如,经常不会经常遇到次正常的长数值计算的几毫秒)到主要问题(例如引入潜在的计时方面)通道进入与安全相关的系统)。
问题中给出的解决方案确实依赖interp
本身既不是次正规,又不是1.0
。