C++ 模数(浮动)与分支
给定两个执行相同操作的表达式(C++ 模数(浮动)与分支,c++,c,modulus,branch-prediction,C++,C,Modulus,Branch Prediction,给定两个执行相同操作的表达式([-3.14,3.14]->[0,6.28]): 或 这两者在性能上有一般性差异吗 编辑: 假设这样一个表达式被多次调用(因此性能是相关的),并且输入a每次都不同。(使问题更直接地得到回答) 这两者在性能上有一般性差异吗 当然,分析是最好的,但作为一般指导,考虑优化潜力。 编译器通常会在A类型的整个范围内进行优化,而不是[-3.14,3.14]t是一个简单的计算,易于优化 此外,在C中,m计算被强制进入double,当然还有一个函数调用。更多的限制意味着更少的优化可
[-3.14,3.14]->[0,6.28]
):
或
这两者在性能上有一般性差异吗
编辑:
假设这样一个表达式被多次调用(因此性能是相关的),并且输入a
每次都不同。(使问题更直接地得到回答)
这两者在性能上有一般性差异吗
当然,分析是最好的,但作为一般指导,考虑优化潜力。
编译器通常会在A
类型的整个范围内进行优化,而不是[-3.14,3.14]t
是一个简单的计算,易于优化
此外,在C中,m
计算被强制进入double
,当然还有一个函数调用。更多的限制意味着更少的优化可能性t
可以使用最佳FP宽度
推荐a>0?a:a+6.28
作为一般首选方法
给出了两个做相同事情的表达式 但是他们在域上做了而不是做同样的事情
[-3.14,3.14]
大约四分之一的double
在[0…1.0]范围内m
使用a+6.28
将在该加法中丢失至少3到所有位的精度。优点:t
范围不同:t
的范围是[0,6.28]m
的范围是[0,6.28],而不是[0,6.28]
考虑更高的目标 很明显,这段代码正在尝试三角范围缩减。要做到这一点,比基本的正弦、余弦、切线计算本身要困难。请参阅
如果代码是以度而不是弧度开始的,那么首先考虑范围缩小的范围。
大画面
根据
a
的派生方式或t
,m
的使用方式,甚至可能会有更好的性能想法。因此,如果性能确实是一个问题,则需要周围的代码,否则我们会错误地进行微优化。有一个非常简单的答案:测量。编写一个基准测试并尝试一下(确保已打开优化器)。这是知道一件事是否比另一件事快的唯一方法。当然,但我想我正在寻找一个更符合经验的答案。如果没有,那很好。但我想知道一件事是否比另一件事有普遍的好处。godbolt.org对此很有帮助。请参阅您的两个解决方案与gcc一起生成的程序集:另外,C++的另一个选择。通常在使用角度时,人们更喜欢从[0, 2π]映射到[]。−π、 π]而不是相反,从接近零的浮点精度的提高中获益。将较小的负值映射为较大的值会失去精度。
a > 0? a : a + 6.28
fmod(a + 6.28, 6.28)
// Tertiary
t = a > 0? a : a + 6.28
// vs fmod
m = fmod(a + 6.28, 6.28)