模数(浮动)与分支

Modulus (Float) vs Branch

给定 2 个做同样事情的表达式 ([-3.14, 3.14] -> [0, 6.28]):

a > 0? a : a + 6.28

fmod(a + 6.28, 6.28)

两者在性能上是否存在普遍差异?

编辑: 假设这样的表达式被多次调用(这样性能是相关的)并且输入 a 每次都不同。 (为了让问题更直接地回答)。

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

Is there a general difference between the two in performance?

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

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

此外,根据 FLT_EVAL_METHOD,在 C 中,m 计算被强制进入 double 并且肯定是函数调用。更多的限制意味着更少的优化可能性。 t 可能会使用最佳 FP 宽度。

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


Given 2 expressions that do the same thing

但他们在域[-3.14, 3.14]

上做同样的事情

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

范围不同:
t的范围是[0, 6.28]
m的取值范围是[0, 6.28),不是[0, 6.28]


考虑更高的目标

很明显,代码正在尝试缩减三角函数范围。要做到这一点比基本正弦更难。余弦、正切计算本身。请参阅 大参数的参数减少: 好到最后.

如果代码以度而不是弧度开头,请首先考虑 以度为单位的范围缩减。


大图

根据 a 的派生方式或 tm 的使用方式,甚至可能有更好的性能想法。因此,如果性能确实是一个问题,则需要周围的代码,否则我们会错误地进行微优化。