代码之家  ›  专栏  ›  技术社区  ›  Nick Strupat

是否可以通过编程确定哪个更快;使用余数运算符还是条件?

c++
  •  1
  • Nick Strupat  · 技术社区  · 14 年前
    wraparound_counter & operator ++() {
        m_count = (m_count + 1) % upper_limit;
        /*if (upper == m_count)
            m_count = lower;
        ++m_count;*/
        return *this;
    }
    

    据我所知,在某些系统上,使用剩余运算符技巧将更快,但在其他系统上,条件将更快。有没有什么方法可以确定哪个在编译时(或运行时)更快?

    5 回复  |  直到 14 年前
        1
  •  2
  •   Nordic Mainframe    14 年前

    对于大多数平台,您可以假设条件更快。这是因为大多数分支预测失误代价高昂的现代体系结构都具有某种形式的条件移动指令,编译器将利用这些指令执行请求的检查和分配。例如,我的GCC将其翻译为:

    n++; if (n==1234) n=0;
    

    对于x86_64(和x86)而言:

        addl    $1, %esi  ; %esi=n
        cmpl    $1234, %esi
        cmove   %edx, %esi ; %edx contains 0
    

    (从Pentiumpro开始提供CMove。)

    这是手臂拇指:

        add     r3, r3, #1
        cmp     r3, r1
        moveq   r3, #0 ; <- conditional move
    

    所有 武器有条件执行。

    等等。总结一下:你需要一个架构

    • 非常快的除法/模
    • 昂贵的分支预测失误
    • 无条件移动

    以模戏法作为最快的结束。**如果有这样的建筑,请告诉我。我总是对这些事感兴趣。

        2
  •  2
  •   sellibitze    14 年前

    除非您需要程序是可交叉编译的,否则您可以将基准测试作为构建过程的一部分。根据结果,您可以选择特定的实现并继续编译应用程序。

        3
  •  1
  •   koo5    14 年前

    循环运行一百万次?

        4
  •  1
  •   mikera    14 年前

    你需要做基准测试。

    由于分支预测失误,条件值可能很昂贵。

    另一方面,在许多处理器上,除法比简单的比较更昂贵。

    它可以根据运行的平台、运行的循环类型、上限有多大、编译器正在执行的优化等进行任意选择。

        5
  •  1
  •   Kelly S. French    14 年前

    从技术上讲,如果不同时执行这两项操作,就不可能确定哪个更快。就为完成工作而调用的代码而言,当您需要执行其中一个选项时,已经太迟了。您可以有一个例程,在应用程序初始化阶段对两个示例例程进行基准测试,然后设置一个标志。但这引入了一个全新的测试,为每个目标调用增加了开销。归根结底是:

    1. 在构建时选择适当例程的专用代码
    2. 运行时基准测试(增加开销)
    3. 针对您的平台并研究指令集实现细节
    4. 让编译器为您完成所有这些工作

    除非您正在构建嵌入式系统或具有非常具体的性能调优要求,4是您的最佳选择。