[[可能]]和[[不太可能]]影响程序汇编的简单示例? [英] Simple example where [[likely]] and [[unlikely]] affect program assembly?

查看:17
本文介绍了[[可能]]和[[不太可能]]影响程序汇编的简单示例?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C++20向该语言引入了[[likely]][[unlikely]]属性,这些属性可用于允许编译器针对以下情况进行优化:一条执行路径比另一条执行路径更可能或更不可能

考虑到不正确的分支预测的代价,这似乎是一个在代码的性能关键部分非常有用的功能,但我不知道它实际上会导致编译器做什么。

有没有一段简单的代码,添加[[likely]][[unlikely]]属性会更改编译器的程序集输出?也许更重要的是,这些更改有什么作用?

我创建了一个简单的示例,以了解程序集是否有任何差异,但该示例似乎太简单,无法实际显示对程序集的任何更改:

void true_path();
void false_path();

void foo(int i) {
    if(i) {
        true_path();
    } else {
        false_path();
    }
}
void bar(int i) {
    if(i) [[likely]] {
        true_path();
    } else [[unlikely]] {
        false_path();
    }
}

View the compiled assembly here.

推荐答案

看起来,GCC身上有个BUG。如果您有两个相同的函数,除[[likely]]属性外,GCC将其折叠错误。

但如果您只使用一个函数,并在[[likely]]/[[unlikely]]之间切换,则程序集将更改。

因此,此函数:

void bar(int i) {
    if(i) [[unlikely]] {
        true_path();
    } else [[likely]] {
        false_path();
    }
}

编译为:

bar(int):
        test    edi, edi
        jne     .L4
        jmp     false_path()
.L4:
        jmp     true_path()

和这个:

void bar(int i) {
    if(i) [[likely]] {
        true_path();
    } else [[unlikely]] {
        false_path();
    }
}

编译为:

bar(int):
        test    edi, edi
        je      .L2
        jmp     true_path()
.L2:
        jmp     false_path()

注意,条件已经改变:如果i为非零值,则第一个版本跳转,如果i为零,则第二个版本跳转。

这与属性一致:GCC生成代码,其中条件跳转发生在不太可能的路径中。

这篇关于[[可能]]和[[不太可能]]影响程序汇编的简单示例?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆