混合函数-增加浮点出现次数

  • 本文关键字:函数 增加 混合 c++ c++11
  • 更新时间 :
  • 英文 :


我浏览了一个代码库,发现了以下模板函数:

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

有人能强调为什么这是真的吗?

正如Paul R在评论中所说,这些评论可能指的是非正规(我通常认为它们被描述为亚正规,所以会使用这个术语)数字,它们填补了浮点运算中零附近的下溢空白。

如果ab的值足够接近,则a-b将产生亚正常值。当这些值完全在硬件中处理时,性能通常会受到影响。在硬件中有一些技术可以缓解这种情况,但在一些现代处理器中,涉及子规范的指令可能比作用于正常值的相同指令花费100多倍的时间。如果这些值完全在软件中处理(例如,硬件指令不直接处理它们,并且出现浮点异常,必须在软件中捕获并进行排序),那么性能几乎总是会下降。

根据应用程序的类型,所产生的问题可能从无关紧要(例如,对于不经常遇到子规范的长数值计算,额外的几毫秒)到主要问题(例如,在安全相关系统中引入潜在的定时侧信道)不等。

问题中给出的解决方案确实依赖于interp本身既不是亚正规,也不是太接近1.0

最新更新