C 我们可以比较二进制运算符的基准/性能吗?

C 我们可以比较二进制运算符的基准/性能吗?,c,algorithm,performance,benchmarking,C,Algorithm,Performance,Benchmarking,我的问题是关于二进制运算符的性能(执行时间/基准),我们能否举例说明执行a+b比a%b快。 我的问题不仅限于那些运营商(+和%),还包括: 加法运算符(+和-) 乘法运算符(*,/,%…) 比较运算符(,这些运算符的性能取决于平台。如果使用“slow”运算符表示的操作可以使用“fast”运算符实现,则您通常可以期望编译器提取该运算符并发出快速代码。不要使用“faster”操作数只是因为有人告诉您它们在没有基准测试的情况下速度更快 但是,一般来说,操作员可以大致按照以下等级进行速度分类: 零周期

我的问题是关于二进制运算符的性能(执行时间/基准),我们能否举例说明执行
a+b
a%b
快。 我的问题不仅限于那些运营商(+和%),还包括:

  • 加法运算符(+和-)
  • 乘法运算符(*,/,%…)

  • 比较运算符(,这些运算符的性能取决于平台。如果使用“slow”运算符表示的操作可以使用“fast”运算符实现,则您通常可以期望编译器提取该运算符并发出快速代码。不要使用“faster”操作数只是因为有人告诉您它们在没有基准测试的情况下速度更快

    但是,一般来说,操作员可以大致按照以下等级进行速度分类:

  • 零周期:在数组表达式
    a[b]
    中,在解引用之前的直接加法通常是免费的。一元
    +
    也是免费的
  • 一个周期:对于整数操作数:二进制
    +
    -
    &
    ^
    ^
    ,一元
    -
    ~
    ,如果结果未以数字形式使用,则在整数类型或指针之间强制转换:
    =
    颂歌>
  • 三到四个周期:二进制
    *
    整数操作数,浮点操作数:二进制
    +
    -
  • 20个周期(?):整数二进制
    /
    %
  • 50个周期(?):浮点
    /
    fmod

  • 您的里程数可能会有所不同,如果有疑问,请不要依赖此表进行基准测试。

    FuzzXL回答中的几个补充:

    • 在现代Intels和AMD上,+和*的吞吐量大致相同(非常快),但*通常具有更高的延迟。吞吐量是指您发出命令的频率,延迟是指在结果准备就绪之前您必须等待的时间(CPU执行其他无序的操作时)
    • 一些RISC CPU有相当昂贵的移位(即Xbox360和PS3上使用的移位)
    • 一段时间前,他们“修复”了除法,除法不再像以前那么慢了。我认为FP除法现在大约有16个时钟(整数可能会慢一些)
    • 虽然比较本身都很快,但如果预测失误,条件跳转可能会非常慢(因为CPU必须先转储它预期执行的所有内容)。CPU是否能够预测比较结果取决于它们的随机性(当同一检查执行多次时)。但是,即使它们倾向于遵循一种模式,每个跳转都会占用一个分支预测槽,因此它可能会从中逐出另一个跳转,而另一个分支将遭受预测失误的惩罚。换句话说,比较可能会非常昂贵

    非常类似于如果您需要详细信息:将相关代码编译到程序集,查看程序集并查看。编写一个小程序,启动一个时钟,执行数百万次相同的操作,停止时钟并进行比较。这有点误导,因为它不考虑多次调度、指令重新排序等。此外,浮点p点运算通常随操作数的值而变化。@Gene,这就是我说“您的里程可能会变化”的原因。@fuzzxl因此,如果我使用移位和按位运算符(一个周期)实现一个算法,它将比使用/或%(20个周期)实现的算法更优化?@WaelBoutglay可能是。编译器将把
    a/32
    之类的东西优化为
    a>>5
    ,所以你不必担心这些小细节。