根据条件然后三元运算符获得值的更快方法?

Ela*_*iss 7 c c++ optimization

这就是我想要实现的目标.这很简单:

unsigned int foo1(bool cond, unsigned int num)
{
    return cond ? num : 0;
}
Run Code Online (Sandbox Code Playgroud)

Assmebly:

    test    dil, dil
    mov     eax, 0
    cmovne  eax, esi
    ret
Run Code Online (Sandbox Code Playgroud)

我的问题是,有更快的方法吗?以下是我想到的一些方法:

使用乘法:

unsigned int foo2(bool cond, unsigned int num)
{
    return cond * num;
}
Run Code Online (Sandbox Code Playgroud)

ASSMBLY:

    movzx   eax, dil
    imul    eax, esi
    ret
Run Code Online (Sandbox Code Playgroud)

使用内存访问:

unsigned int foo3(bool cond, unsigned int num)
{
    static const unsigned int masks[2] = { 0x0, 0xFFFFFFFF };
    return masks[cond] & num;
}
Run Code Online (Sandbox Code Playgroud)

部件:

    movzx   edi, dil
    mov     eax, DWORD PTR foo3(bool, unsigned int)::masks[0+rdi*4]
    and     eax, esi
    ret
Run Code Online (Sandbox Code Playgroud)

使用一些技巧:

unsigned int foo4(bool cond, unsigned int num) 
{
    return (0 - (unsigned)cond) & num;
}
Run Code Online (Sandbox Code Playgroud)

部件:

    movzx   eax, dil
    neg     eax
    and     eax, esi
    ret
Run Code Online (Sandbox Code Playgroud)

现在,乘法产生最少的指令,我认为这是最好的选择,但我不确定imul.有什么建议?

提前致谢,

小智 1

乘法和内存访问通常比简单的 if 语句花费更多的时间。如果要优化此代码,最好的方法是仅使用“and”或“or”指令(将其设置为内联以避免顺便调用函数)。

这是使用掩码而不是布尔值的函数的“优化”示例:

inline unsigned int foo1(unsigned int mask, unsigned int num)
{
  return mask & num;
}
Run Code Online (Sandbox Code Playgroud)

您的通话将如下所示:

foo1(0, 10);     /* Returns 0  */
foo1(~0, 10);    /* Returns 10 */
Run Code Online (Sandbox Code Playgroud)

  • 如果你写“-cond & num”,你也可以用“bool cond”保留原始签名。使用 Clang,这实际上使用“cmovne”编译为与第一个示例相同的代码。 (2认同)