【问题标题】:Branching without if statement没有 if 语句的分支
【发布时间】:2012-12-20 15:37:02
【问题描述】:

是否可以使用if 语句分支代码?

【问题讨论】:

    标签: if-statement language-agnostic


    【解决方案1】:

    取决于“分支”和“如果”的含义。以下任何一个分支,没有“if”。

    switch (foo) {
    
    }
    

    或者三元运算符,如果你不计算:

    x == 0 ? doFunc1() : doFunc2()
    

    如果你的语言支持函数指针:

    funcArray[selectedOption]()
    

    你可以傻傻的去做:

    boolean once = true;
    while (condition && once) {
      doAWhichNeverReturns();
      once = false; 
    } 
    doB();
    

    但我认为这并不能真正回答您的问题,因为我不知道您要做什么。

    【讨论】:

    【解决方案2】:

    是的,你可以,GPU 风格。

    假设你有一个分支的函数,并在最后返回一个值。

    float function( float input )
    {
        if( input > 0 )
        {
            // do stuff
            finalValue = 2+4+8*input;
            return finalValue ;
        }
        else
        {
            // do other stuff
            finalValue = 1+input;
            return finalValue ;
        }
    }
    

    要做到这一点没有分支,你可以编写GPU风格的代码:即评估两个分支,然后在最后扔掉你不想要的那个 em>。

    float function( float input )
    {
        // do stuff..regardless
        finalValue1 = 2+4+8*input;
    
        // do other stuff..regardless
        finalValue2 = 1+input;
    
        bool resultMask = input > 0 ; // 1 if should use finalValue1.
        return finalValue1*resultMask   +   finalValue2*(1 - resultMask) ;
    }
    

    所以你有它。没有分支的分支,没有 if 语句的 if 语句。

    【讨论】:

    • 但实际的if 仍然存在于input > 0 表达式中,只是语法发生了变化。从性能的角度来看,由于双重评估,它可能比原来的更差
    • @icepack:我觉得你错了,这里没有if。最重要的是,这段代码从不分支或跳转,因此不会停止指令流水线
    • @mvp 没有if 语法,但它在语义上存在于input > 0 表达式中,预计会产生类似于if 的汇编代码。请参阅下面的@James 答案。我同意流水线。
    • @icepack:不是真的。例如,x86 上的 input > 0 只是一个 cmp 指令,它是纯算术的——cmp a, b 设置测试标志,就像您计算了 a - b 一样。 “分支”仅在您使用条件跳转指令(例如,jajg)时发生,该代码不会生成该指令。我正在简化——处理浮点数的细节有点不同——但原则是成立的。
    • @JonPurdy 是的,它设置了标志。接下来如何处理结果?
    猜你喜欢
    • 2016-05-24
    • 2020-03-20
    • 2014-02-26
    • 2016-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    相关资源
    最近更新 更多