可能(x) 和 __builtin_expect((x),1)

2023-11-26

我知道内核使用likely and unlikely宏惊人。宏的文档位于内置函数:long __builtin_expect(long exp, long c)。但他们并没有真正讨论细节。

编译器到底是如何处理的likely(x) and __builtin_expect((x),1)?

它是由代码生成器还是优化器处理的?

它取决于优化级别吗?

生成的代码的示例是什么?


我刚刚在 gcc 上测试了一个简单的例子。

对于 x86,这似乎由优化器处理并取决于优化级别。尽管我猜这里的正确答案是“这取决于编译器”。

生成的代码取决于 CPU。一些CPU(我立即想到sparc64,但我确信还有其他CPU)在条件分支指令上有标志,告诉CPU如何预测它,因此编译器根据构建生成“预测真/预测假”指令在编译器的规则和代码的提示中(例如__builtin_expect).

英特尔在这里记录了他们的行为:https://software.intel.com/en-us/articles/branch-and-loop-reorganization-to-prevent-mispredicts。简而言之,Intel CPU 上的行为是,如果 CPU 之前没有有关分支的信息,它将预测不太可能采用前向分支,而可能采用后向分支(考虑循环与错误处理)。

这是一些示例代码:

int bar(int);
int
foo(int x)
{
    if (__builtin_expect(x>10, PREDICTION))
        return bar(10);
    return 42;
}

编译(我使用 omit-frame-pointer 使输出更具可读性,但我仍然在下面清理它):

$ cc -S -fomit-frame-pointer -O0 -DPREDICTION=0 -o 00.s foo.c
$ cc -S -fomit-frame-pointer -O0 -DPREDICTION=1 -o 01.s foo.c
$ cc -S -fomit-frame-pointer -O2 -DPREDICTION=0 -o 20.s foo.c
$ cc -S -fomit-frame-pointer -O2 -DPREDICTION=1 -o 21.s foo.c

00.s 和 01.s 之间没有区别,因此这表明这取决于优化(至少对于 gcc 而言)。

这是(清理后的)生成的 20.s 代码:

foo:
    cmpl    $10, %edi
    jg  .L2
    movl    $42, %eax
    ret
.L2:
    movl    $10, %edi
    jmp bar

这是 21.s:

foo:
    cmpl    $10, %edi
    jle .L6
    movl    $10, %edi
    jmp bar
.L6:
    movl    $42, %eax
    ret

正如预期的那样,编译器重新排列了代码,以便我们不希望采用的分支在前向分支中完成。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可能(x) 和 __builtin_expect((x),1) 的相关文章

  • 将 ARGB 拆分为字节值

    我有一个 ARGB 值存储为 int 类型 它是通过调用 ToArgb 来存储的 我现在想要来自 int 值的各个颜色通道的字节值 例如 int mycolor 16744448 byte r g b a GetBytesFromColor
  • 线程独占数据:如何存储和访问?

    NET 中是否有可能将对象实例绑定到线程的当前执行上下文 这样在代码的任何部分我都可以做类似的事情CurrentThread MyObjectData DoOperation 并确保我访问特定于线程的数据 谢谢 你可以看一下线程静态属性 h
  • 为什么使用数组索引循环数组比指针访问慢?

    我正在读Kochan的书 Programming in C 在第 14 页的 指针和数组 部分中 264 他说 一般来说 索引数组的过程比执行索引过程花费更多的时间 访问指针内容的过程 其实这也是主要原因之一 为什么使用指针来访问数组的元素
  • C语言实现延时函数

    我想使用空循环实现延迟函数 但是完成一次循环所需的时间取决于编译器和机器 我希望我的程序自行确定时间并将程序延迟指定的时间 谁能给我任何想法如何做到这一点 注意 有一个名为delay 的函数可以将系统暂停指定的毫秒 是否可以在不使用此功能的
  • 如何用另一个静态变量初始化一个静态变量?

    静态1 hpp include
  • 更改图像颜色与透明背景

    我需要使用 c System Drawings 将透明背景上带有绿色圆圈的图像加载到位图图像中 这是最简单的部分 但是 我需要在将其添加到更大的图像之前更改圆圈的颜色 而不影响周围的透明度 就我而言 我需要将圆圈颜色更改为黄色并将其添加为太
  • C 中的 '\0' 和 printf()

    在 C 入门课程中 我了解到在存储字符串时存储空字符 0在它的最后 但是如果我想打印一个字符串怎么办 printf hello 虽然我发现它并没有结束 0通过以下声明 printf d printf hello Output 5 但这似乎不
  • C++ 并行任务的开销

    我有以下简单的功能 include
  • 使用 LINQ 展平嵌套字典

    所以我有一本形式的字典Dictionary
  • 有没有办法找到dll公开的所有函数

    我一直在寻找一种方法来获取映射到 dll 中函数名称的所有字符串 我的意思是您可以调用 GetProcAddress 的所有字符串 如果你对 dll 进行十六进制转储 符号 字符串 就在那里 但我认为必须有一个系统调用来获取这些名称 如果您
  • 是否自初始化 'A a = a;'允许吗?

    此代码在运行时在复制构造函数中失败 但编译器 MSVS2008 没有发出警告 您能解释一下 最好引用标准 这段代码是否非法或什么 我理解 A a a 永远不应该写在第一位 但我正在寻找理论背景 class A public A p new
  • FFplay成功移入我的Winform中,如何设置它无边框?

    用这个代码 在 C 应用程序中显示 tcp 视频流 来自 FFPLAY FFMPEG https stackoverflow com questions 14201894 show a tcp video stream from ffpla
  • 将旧的 Unity 代码升级到 Unity 5

    在触发按钮上播放动画的代码似乎不起作用 我在 Youtube 上看到了一个视频 内容很简单animation Play 它可以在该视频上运行 但我无法让它在我的计算机上运行 我做错了什么还是团结改变了它 请帮助我在网上找不到解决方案 所有
  • 为什么最小的 int -2147483648 的类型为“long”? [复制]

    这个问题在这里已经有答案了 对于一个学校项目 我必须编写 C 函数 printf 的代码 一切进展顺利 但有一个问题我找不到好的答案 所以我来了 printf PRINTF d t d n 2147483648 告诉我 gcc Werror
  • C++ 模板参数数量错误(2,应该是 1)

    我使用 C 并行快速排序程序进行了测试 如下所示 首先使用列表作为容器 然后我转移到通用容器类型 但它报告了标题错误 可以帮忙解决这个问题吗 include
  • C中使用JNI从对象获取对象

    public class Student private People people private Result result private int amount 这是 Java 中类的示例 在C中 我试图获取 学生 中的 人 但失败了
  • 为什么我无法通过 lambda 捕获“this”指针?

    考虑以下代码 class A public void foo auto functor this A a this auto functor a The compiler won t accept this instead of a a g
  • 使用 DataGridViewCheckboxCell 真正禁用 DataGridView 中的复选框

    有谁知道如何使用 DataGridViewCheckboxCell 禁用 DataGridView 中的复选框 我可以将其设置为只读 并设置背景颜色 但我无法让复选框本身显示为禁用状态 有什么想法吗 Guess 你必须自己画 http so
  • Membership.ValidateUser() 的目的是什么

    我一直在学习有关MembershipProvider类 我认为Membership ValidateUser 方法应该用于登录用户 然而我刚刚了解到有一个FormsAuthentication Authenticate 目的是什么Valid
  • Selenium - 模式对话框存在 - 如何接受信息?

    我有以下问题 在页面上提交一些日期后 我有一个如图所示的模式对话框 我想单击 ENTER 来浏览该模式 但它不起作用 我有以下代码 driver FindElement By CssSelector input submit Click A

随机推荐

  • 在 ASP.Net Core 中发布表单数据时出现 400 状态错误 [关闭]

    Closed 这个问题需要调试细节 目前不接受答案 我正在开发一个 ASP Net Core 2 0 应用程序并在 Linux Nginx Kestrel 上运行它 在开发环境 Windows 10 上一切运行顺利 此外 在项目目录中使用
  • 托管和设置自己的闪亮应用程序,无需闪亮服务器

    我正在尝试为我的同事提供闪亮的应用程序 而他们无需运行甚至无需安装 R 所以我读了这个网页并找到了这句话 如果您熟悉网络托管或有权访问 IT 部门 您可以自己托管您的 Shiny 应用程序 在下面 分享为网页 部分 我怎样才能做到这一点 问
  • Try It 演示中的 Google Drive SDK 更新(删除/插入)所有者权限 500 错误

    我正在开发一个应用程序 它应该为 Google Apps 管理员提供重新分配文件所有权的能力 目前我正在使用 Google Drive SDK for NET 和 C 代码 当我在 Google Drive SDK 测试演示中进行身份验证时
  • 如何在 Twig 中使用 sprintf 格式化数字?

    我需要格式化一个数字 在 PHP 中 我会使用sprintf 05d lineNumber 在 Symfony 2 Twig 模板中 我应该使用什么代码 If i之前是 4 然后将其添加到 Twig 模板后 02d format i 它将成
  • 找出 ASP.NET 身份验证票证过期的原因

    我需要帮助弄清楚为什么我的身份验证票证在我的托管网站上大约一个小时后就过期了 但是 如果我在本地运行该站点 身份验证票证将在正确的时间内保持活动状态 这是我的本地主机 web config
  • Steam 市场货币和 XML 格式

    我试图在市场上以某种货币获取商品页面 尝试添加 Accept Language ru RU r n and Accept Language ru RU ru r n and Accept Language ru ru RU q 0 8 r
  • git 清理旧分支

    我想创建一个 git 命令来删除当前分支中包含所有提交的任何分支 例如 git branch groups master git cleanup branches deleted groups all commits are include
  • 删除向量开头和结尾的零

    我有一个像这样的向量 x lt c 0 0 0 0 4 5 0 0 3 2 7 0 0 0 我只想保留位置 5 到 11 的元素 我想删除开头和结尾的零 对于这个向量来说 这很容易 因为它很小 我有非常大的数据 需要所有向量的通用信息 尝试
  • PostgreSQL 忽略时间戳列上的索引

    我创建了下表和索引 CREATE TABLE cdc auth user cdc auth user id bigint NOT NULL DEFAULT nextval cdc auth user id seq regclass cdc
  • 使用键盘快捷键打开浏览器操作的弹出窗口

    我正在开发一个带有浏览器操作弹出窗口的 Google Chrome 扩展程序 当用户单击该图标时 会出现弹出窗口 Is there a way to open this popup with a keyboard shortcut like
  • 如何检查 zip 存档中是否存在文件

    我有 zip 存档 解压后我需要检查 zip 存档中是否存在 moduleConfig xml 我怎样才能做到这一点 我试试这个 zip new ZipArchive if zip gt open test zip TRUE if file
  • 获取 SQL Server 2000 中最后插入的 UNIQUEIDENTIFIER

    The OUTPUT子句与 SQL Server 2005 兼容 但与 SQL Server 2000 不兼容 如何将此命令转换为在 SQL Server 2000 中工作 CREATE TABLE sample ID uniqueiden
  • 线程接收错误参数

    我需要在线程中运行具有给定参数的方法 我注意到当我运行它时 参数错误 对于给出的示例 我有一个数组int output与数字1 7 对于每个数字 我使用以下方法创建一个线程WriteInt i 我希望输出以任意顺序为 1 7 但我始终看到一
  • AWK 输出到 bash 数组

    我试图将一个简单命令的内容放入 bash 数组中 但是遇到了一些麻烦 df h awk print 5 6 给出我的系统上文件系统的使用百分比 输出看起来像这样 1 dev 1 dev shm 1 var run 0 var lock 22
  • ConcurrentDictionary 和 ConcurrentQueue 的这种组合是线程安全的吗?

    我在以下代码中使用 NET 4 中的 ConcurrentDictionary 和 ConcurrentQueue 类 这段代码是线程安全的吗 如果不是 我怎样才能使其线程安全 public class Page public string
  • 如何从 PyQt 中的 QListView 中选择项目

    我是 PyQt 的新手 所以我试图从 QListView 中获取所选项目 我能够获取所选项目的索引 但我无法获取索引的值 请有人帮助我 这是代码 import sys import os from PyQt4 import QtCore Q
  • 通过 COM 从 VC++ 实例化 C# 对象时出现类未注册错误

    在 VC 项目中 我尝试创建 C 项目中包含的 C 类的实例 通过 COM Facts C 和 C 项目均使用 NET 4 0 编译 C dll 正在使用注册regasm 代码库 CSharpProjectName dll 并且 Windo
  • 在canEditRowAtIndexPath方法中,UITableView的reloadData无法正常工作?

    在我的应用程序中 我重新加载 TableView tablView reloadData 从 TableView 中删除行后canEditRowAtIndexPath方法总是调用 透水 总行数 例如 如果我有5我的 TableView 上的
  • Laravel 5 实现多个 Auth 驱动程序

    Synopsis 我正在构建一个至少具有两个身份验证级别的系统 并且两个级别在数据库中都有单独的用户模型和表 在谷歌上快速搜索 迄今为止唯一的解决方案是使用 MultiAuth 包 该包可以在多个驱动程序上安装Auth My goal 我正
  • 可能(x) 和 __builtin_expect((x),1)

    我知道内核使用likely and unlikely宏惊人 宏的文档位于内置函数 long builtin expect long exp long c 但他们并没有真正讨论细节 编译器到底是如何处理的likely x and builti