0

这可能是一个愚蠢的问题,出于无知而问。

是一个描述分支预测的链接。看起来这在哑 CPU 上效率不高,为什么编译器不能只生成一个二元素跳转表?看看下面的代码:

int main(){
    bool c = true;
    if(c);        /* do something here.      */
    else;         /* do else something here. */
}

使用编译器资源管理器,这会生成以下机器代码 (-O0):

main:                                   # @main
        push    rbp
        mov     rbp, rsp
        mov     dword ptr [rbp - 4], 0
        mov     byte ptr [rbp - 5], 1
        test    byte ptr [rbp - 5], 1
        je      .LBB0_2
        jmp     .LBB0_3
.LBB0_2:
        jmp     .LBB0_3
.LBB0_3:
        mov     eax, dword ptr [rbp - 4]
        pop     rbp
        ret

这当然有一个分支,而以下代码:

int main(){
    bool c = true;
    using jmptable_t = void(*)();
    jmptable_t jmptable[2] = {nullptr, nullptr};
    jmptable[c];
}

生成:

main:                                   # @main
        push    rbp
        mov     rbp, rsp
        sub     rsp, 32
        mov     byte ptr [rbp - 1], 1
        lea     rdi, [rbp - 32]
        xor     esi, esi
        mov     edx, 16
        call    memset@PLT
        xor     eax, eax
        add     rsp, 32
        pop     rbp
        ret

其中大部分是为设置跳转表而生成的。这里没有分店。 在这里,我将两种方法的速度与 -O0 进行比较。跳转表始终比 if 语句快,这让我感到惊讶,因为我认为跳转表的优化程度较低。

也许我的测试不准确?

问题:

  • 在一般环境中哪个更快,优化可能是 O1 或 O2?
  • 当我将优化设置为 O3 时,if 语句变得非常快。为什么是这样?编译器做了哪些优化?
4

0 回答 0