模数(浮动)vs分支

时间:2018-11-16 16:01:29

标签: c++ c modulus branch-prediction

给出2个执行相同操作的表达式([-3.14, 3.14] -> [0, 6.28]):

a > 0? a : a + 6.28

fmod(a + 6.28, 6.28)

两者在性能上是否存在一般差异?

编辑: 假设多次调用这样的表达式(因此性能是相关的),并且每次输入a都不相同。 (使问题更直接可回答)。

1 个答案:

答案 0 :(得分:1)

// Tertiary
t = a > 0? a : a + 6.28
// vs fmod
m = fmod(a + 6.28, 6.28)
  

两者在性能上是否存在一般差异?

当然,概要分析是最好的@NathanOlive,但作为一般指南,请考虑优化的潜力。

编译器通常会在a类型的整个范围内进行优化,而不是[-3.14,3.14]。 t是一种简单的计算,很容易优化。

此外,根据FLT_EVAL_METHOD,在C语言中,m的计算被强制到double中,当然也强制进行函数调用。更多的限制意味着更少的优化可能性。 t可以使用最佳FP宽度。

推荐 a > 0 ? a : a + 6.28作为首选方法。


  

给出2个执行相同操作的表达式

但是他们在域[-3.14, 3.14]

上做同样的事情

所有double中约1/4在[0 ... 1.0]范围内。 m的{​​{1}}使用率将至少损失3到所有个精度位。优势:a + 6.28

范围不同:
t的范围是[0,6.28]
t的范围是[0,6.28),而不是[0,6.28]


对更高目标的考虑

很明显,代码正在尝试缩小三角范围。做到这一点比基本的正弦困难。余弦,切线计算本身。参见ARGUMENT REDUCTION FOR HUGE ARGUMENTS: Good to the Last Bit

如果代码以度而不是弧度开头,请首先考虑advantages的度数范围缩小。


更大的图片

根据ma的使用方式,t的使用可能会带来更好的性能。因此,如果真正要关注性能,那么就需要周围的代码,否则我们就不正确地进行微优化。