0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux内核中的jump label原理与逻辑及运行过程

Linux阅码场 来源:CSDN技术社区 作者:dog250 2021-03-25 14:02 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

jump label机制进入Linux内核已经很多很多年了,它的目的是 消除分支。 为了达到这个目的,jump label的手段是 修改分支处的代码。

~把代码当做数据,代码和数据在冯诺伊曼计算机中得到了统一~

本质上,jump label作用于下面的逻辑:

e0bbcc26-8cdd-11eb-8b86-12bb97331649.png

静态拆分成了下面的两个逻辑,其一是:

e0e058fc-8cdd-11eb-8b86-12bb97331649.png

或者,其二是:

e12ea246-8cdd-11eb-8b86-12bb97331649.png

但二者不能同时共存。显然,这破坏了通用性和灵活性,带来了高效!

这相当于一个硬熔断,具体详情参见:

本文来一点可以看得见的东西,演示一下真实的jump label & static key。

先看下面的C代码:

e1519dc8-8cdd-11eb-8b86-12bb97331649.png

很简单的代码,也很正确。然而, 如果main函数是一个高频调用的函数,并且在E1,E2是不随着代码逻辑而发生变化,仅仅参数设定的情况下, 那么if语句尽量消除以消除不必要的分支预测,而这正是jump label的用武之地!

我们下面用jump label机制来重写上面的代码,请看:

e18ee192-8cdd-11eb-8b86-12bb97331649.png

e1e3bc44-8cdd-11eb-8b86-12bb97331649.png

e22b2692-8cdd-11eb-8b86-12bb97331649.png

e26cc53e-8cdd-11eb-8b86-12bb97331649.png

e2a16848-8cdd-11eb-8b86-12bb97331649.png

定义JUMP_LABEL宏编译之,看看效果:

e2c8bb50-8cdd-11eb-8b86-12bb97331649.png

如何做到的呢?static_branch_true内联函数是如何判断true or false的呢?

事实上,jump label逻辑修改了代码段,取消了条件判断!这一切都是在update_branch中发生的。我们看下update_branch调用之前,main函数的汇编码:

e31df26e-8cdd-11eb-8b86-12bb97331649.png

在执行了update_branch之后,main函数发生了变化:

e338ed80-8cdd-11eb-8b86-12bb97331649.png

e39d2124-8cdd-11eb-8b86-12bb97331649.png

看样子就是这么回事!

之所以这件事可以发生得如此简单,多亏了一个新的section,即__jump_table,我们通过objdump看看__jump_table的内容:

e3e7c74c-8cdd-11eb-8b86-12bb97331649.png

通过jump_label_demo.c的struct entry结构体,我们直到这个section中包含了多个3元组,包含3个字段:

需要修改的代码地址。

需要jmp到的代码地址。

匹配健。

我们看67064000 00000000按照小端就是0x400667,它就是需要修改的代码地址,而6e064000 00000000按照小端则是0x40066e:

e41fa0e0-8cdd-11eb-8b86-12bb97331649.png

看来,这个__jump_table的item会将jmpq 40066c修改为jmpq 40066e,从而实现了 永久静态分支。

最后,__jump_table的内容就是在每一个内联的static_branch_true函数中被填充的,该参数的参数是一个key,它指示了branch entry三元组中的最后一个字段。

static_branch_true函数的内联非常重要,它实现了将branch entry三元组数据直接插入到__jump_table section,而不是共享同一个函数体。

总之,如果你看代码还是觉得别扭,手敲一遍我上面的示例程序,就理解了,内核里面的也就这么回事,总结一句话:

依靠运行时修改代码而不是依靠状态数据来控制执行流。

我不知道这对于所谓的 通用计算机程序设计 是不是反其道而行之,但在效果上,它确实是一匹好马。不禁感叹, 硬编码读起来是丑陋的,但执行起来却是高效的!

灵活性换高效率,得不偿失,我是这样以为。jump label的本质在于, 将同时刻存在的一套代码沿着时间线在可预期的固定时间点上分割成逻辑相反的两套代码。

硬件性能的提升将会证明jump label就是个笑话。

说两句好话,Linux内核参数,sysctl变量基本上就可以通过jump label来运作,从而替代if判断。

原文链接:https://blog.csdn.net/dog250/article/details/106715700
编辑:lyn

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 数据
    +关注

    关注

    8

    文章

    7314

    浏览量

    93983
  • 逻辑
    +关注

    关注

    2

    文章

    834

    浏览量

    30053
  • 代码
    +关注

    关注

    30

    文章

    4941

    浏览量

    73151
  • LINUX内核
    +关注

    关注

    1

    文章

    318

    浏览量

    23052

原文标题:Linux内核jump label与static key的原理与示例

文章出处:【微信号:LinuxDev,微信公众号:Linux阅码场】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Linux-RT特点及简单应用

    Scheduling),允许内核中断正在执行的任务以执行更高优先级的任务。这可以降低任务响应时间,提高实时性能。 内核锁优化:Linux-RT对内核
    发表于 12-05 07:37

    Linux内核模块的加载机制

    Linux内核模块的加载过程主要包含了ELF解析、动态链接、安全验证和资源管理技术。其核心步骤包括:权限检查→ELF解析→符号重定位→依赖加载→初始化执行。
    发表于 11-25 06:59

    探索操作系统底层的关键接口

      在linux,将程序的运行空间分为内核空间与用户空间(内核态和用户态),在逻辑上它们之间是
    的头像 发表于 11-08 12:42 581次阅读

    deepin亮相2025Linux内核开发者大会

    11 月 1 日,第二十届中国 Linux 内核开发者大会(CLK)在深圳举办。CLK 作为国内 Linux 内核领域极具影响力的峰会,由清华大学、Intel、华为、阿里云、富士通南大
    的头像 发表于 11-05 17:59 623次阅读

    使用rk3568开发板,核0\\1\\3运行linux,核2运行hal,在核0怎么关闭核2

    使用rk3568开发板,核0\\\\1\\\\3运行linux,核2运行hal,想在内核通过smc指令完成核0对核2得启动和关闭,文件系统
    发表于 10-27 10:09

    如何在裸机环境运行KleidiAI微内核

    ,对 KleidiAI 进行了简要概述,并附有相关指南链接,其中详细说明了在 Linux 环境运行 KleidiAI 矩阵乘法 (matmul) 微内核的分步操作,这份指南内容详实且
    的头像 发表于 08-08 15:16 3627次阅读
    如何在裸机环境<b class='flag-5'>中</b><b class='flag-5'>运行</b>KleidiAI微<b class='flag-5'>内核</b>

    Linux内核参数调优方案

    在高并发微服务环境,网络性能往往成为K8s集群的瓶颈。本文将深入探讨如何通过精细化的Linux内核参数调优,让你的K8s节点网络性能提升30%以上。
    的头像 发表于 08-06 17:50 708次阅读

    如何配置和验证Linux内核参数

    Linux系统运维和性能优化内核参数(sysctl)的配置至关重要。合理的参数调整可以显著提升网络性能、系统稳定性及资源利用率。然而,仅仅修改参数是不够的,如何验证这些参数是否生效同样关键。
    的头像 发表于 05-29 17:40 786次阅读

    揭秘,瑞芯微全系拥抱Linux 6.1内核的底层逻辑

    近期,瑞芯微(Rockchip)基本完成了旗下产品Linux6.1BSP内核更新,引发了不小的行业热议。除了低端RK3506依旧使用Buildroot构建系统外,RK3588、RK3576
    的头像 发表于 05-16 08:31 1089次阅读
    揭秘,瑞芯微全系拥抱<b class='flag-5'>Linux</b> 6.1<b class='flag-5'>内核</b>的底层<b class='flag-5'>逻辑</b>

    Linux内核编译失败?移动硬盘和虚拟机的那些事儿

    Linux开发,编译内核是一项常见任务,但不少开发者在移动硬盘或虚拟机环境下尝试时会遭遇失败。本文将简要探讨这些问题的成因,并介绍一些虚拟机使用技巧,帮助大家更好地应对相关问题。在移动硬盘里编译
    的头像 发表于 04-11 11:36 736次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>内核</b>编译失败?移动硬盘和虚拟机的那些事儿

    树莓派4 性能大比拼:标准Linux与实时Linux 4.19内核的延迟测试

    使用的是raspberrypi/linux仓库的rpi-4.19.y-rt分支。同样,在测试,我使用了实时Linux项目中的cyclictest程序。Cyclictest程序
    的头像 发表于 03-25 09:39 656次阅读
    树莓派4 性能大比拼:标准<b class='flag-5'>Linux</b>与实时<b class='flag-5'>Linux</b> 4.19<b class='flag-5'>内核</b>的延迟测试

    基于OpenSBI的linux nommu实现

    :SupervisorSoftwareBinaryInterface软件二进制接口Linux内核工作在S模式下时,不能直接访问机器定时器。而系统的运行依赖于定时器,为了解决这个问
    的头像 发表于 02-08 13:43 1056次阅读
    基于OpenSBI的<b class='flag-5'>linux</b> nommu实现

    腾讯云内核团队修复Linux关键Bug

    Maintainer深感棘手的关键内核bug。 这一改进方案经过严格评审和测试,最终被合并进入后续的Linux LTS(长期支持)版本,标志着腾讯云在操作系统内核领域的技术实力得到了
    的头像 发表于 12-31 10:58 915次阅读

    嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    的比较及时,在遇到一些内核问题时就可以到linux官网的源码查一下是不是有相关的提交记录。 获取芯片原厂的linux源码 每个芯片原厂都有自己的git仓库,他们会把已经开发完成的
    发表于 12-16 13:08

    飞凌嵌入式ElfBoard ELF 1板卡-Linux内核移植之内核简介

    及时,在遇到一些内核问题时就可以到linux官网的源码查一下是不是有相关的提交记录。获取芯片原厂的linux源码每个芯片原厂都有自己的git仓库,他们会把已经开发完成的
    发表于 12-13 09:03