当前位置: 首页 > news >正文

百度关键词搜索排名查询长沙百度网站优化

百度关键词搜索排名查询,长沙百度网站优化,西安网站建设管理,php网站开发套模板文章目录 背景1. static-key的使用方法1.1. static-key定义1.2 初始化1.3 条件判断1.4 修改判断条件 2、示例代码参考链接 背景 内核中有很多判断条件在正常情况下的结果都是固定的#xff0c;除非极其罕见的场景才会改变#xff0c;通常单个的这种判断的代价很低可以忽略除非极其罕见的场景才会改变通常单个的这种判断的代价很低可以忽略但是如果这种判断数量巨大且被频繁执行那就会带来性能损失了。内核的static-key机制就是为了优化这种场景,其优化的结果是对于大多数情况对应的判断被优化为一个NOP指令在非常有场景的时候就变成jump XXX一类的指令使得对应的代码段得到执行。 1. static-key的使用方法 1.1. static-key定义 static_key 结构体的定义如下 #ifdef CONFIG_JUMP_LABELstruct static_key {atomic_t enabled; /** Note:* To make anonymous unions work with old compilers, the static* initialization of them requires brackets. This creates a dependency* on the order of the struct with the initializers. If any fields* are added, STATIC_KEY_INIT_TRUE and STATIC_KEY_INIT_FALSE may need* to be modified.** bit 0 1 if key is initially true* 0 if initially false* bit 1 1 if points to struct static_key_mod* 0 if points to struct jump_entry*/union {unsigned long type;struct jump_entry *entries;struct static_key_mod *next;}; };#else struct static_key {atomic_t enabled; }; #endif /* CONFIG_JUMP_LABEL */如果没有定义CONFIG_JUMP_LABEL则static_key 退化成atomic变量。 1.2 初始化 #define DEFINE_STATIC_KEY_TRUE(name) \struct static_key_true name STATIC_KEY_TRUE_INIT #define DEFINE_STATIC_KEY_FALSE(name) \struct static_key_false name STATIC_KEY_FALSE_INIT#define STATIC_KEY_TRUE_INIT (struct static_key_true) { .key STATIC_KEY_INIT_TRUE, } #define STATIC_KEY_FALSE_INIT (struct static_key_false){ .key STATIC_KEY_INIT_FALSE, }#define STATIC_KEY_INIT_TRUE \{ .enabled { 1 }, \.entries (void *)JUMP_TYPE_TRUE } #define STATIC_KEY_INIT_FALSE \{ .enabled { 0 }, \.entries (void *)JUMP_TYPE_FALSE }false和true的主要区别就是enabled 是否为1. 1.3 条件判断 #ifdef CONFIG_JUMP_LABEL/** Combine the right initial value (type) with the right branch order* to generate the desired result.*** type\branch| likely (1) | unlikely (0)* ----------------------------------------------------* | |* true (1) | ... | ...* | NOP | JMP L* | br-stmts | 1: ...* | L: ... |* | |* | | L: br-stmts* | | jmp 1b* | |* ----------------------------------------------------* | |* false (0) | ... | ...* | JMP L | NOP* | br-stmts | 1: ...* | L: ... |* | |* | | L: br-stmts* | | jmp 1b* | |* ----------------------------------------------------** The initial value is encoded in the LSB of static_key::entries,* type: 0 false, 1 true.** The branch type is encoded in the LSB of jump_entry::key,* branch: 0 unlikely, 1 likely.** This gives the following logic table:** enabled type branch instuction* ----------------------------------------* 0 0 0 | NOP* 0 0 1 | JMP* 0 1 0 | NOP* 0 1 1 | JMP** 1 0 0 | JMP* 1 0 1 | NOP* 1 1 0 | JMP* 1 1 1 | NOP** Which gives the following functions:** dynamic: instruction enabled ^ branch* static: instruction type ^ branch** See jump_label_type() / jump_label_init_type().*/#define static_branch_likely(x) \ ({ \bool branch; \if (__builtin_types_compatible_p(typeof(*x), struct static_key_true)) \branch !arch_static_branch((x)-key, true); \else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \branch !arch_static_branch_jump((x)-key, true); \else \branch ____wrong_branch_error(); \likely(branch); \ })#define static_branch_unlikely(x) \ ({ \bool branch; \if (__builtin_types_compatible_p(typeof(*x), struct static_key_true)) \branch arch_static_branch_jump((x)-key, false); \else if (__builtin_types_compatible_p(typeof(*x), struct static_key_false)) \branch arch_static_branch((x)-key, false); \else \branch ____wrong_branch_error(); \unlikely(branch); \ })#else /* !CONFIG_JUMP_LABEL */#define static_branch_likely(x) likely(static_key_enabled((x)-key)) #define static_branch_unlikely(x) unlikely(static_key_enabled((x)-key))#endif /* CONFIG_JUMP_LABEL */可见同样依赖HAVE_JUMP_LABEL。如果没有定义的话直接退化成likely和unlikely static_branch_unlikely 和 static_branch_likely 只是填充指令的方式不同可以参考上面的代码注释 当static_key为false时都会进入else逻辑语句中。 if (static_branch_unlikely((static_key)))do likely work; elsedo unlikely work1.4 修改判断条件 使用static_branch_enable 和 static_branch_disable可以改变static_key 状态 #define static_branch_enable(x) static_key_enable((x)-key) #define static_branch_disable(x) static_key_disable((x)-key)底层是调用static_key_slow_dec, static_key_slow_dec来改变key-enabled计数。 static inline void static_key_enable(struct static_key *key) {int count static_key_count(key);WARN_ON_ONCE(count 0 || count 1);if (!count)static_key_slow_inc(key); } static inline void static_key_disable(struct static_key *key) {int count static_key_count(key);WARN_ON_ONCE(count 0 || count 1);if (count)static_key_slow_dec(key); }static inline void static_key_slow_inc(struct static_key *key) {STATIC_KEY_CHECK_USE(key);atomic_inc(key-enabled); }static inline void static_key_slow_dec(struct static_key *key) {STATIC_KEY_CHECK_USE(key);atomic_dec(key-enabled); }2、示例代码 下面我们用一段代码来分析static-key对程序分支跳转硬编码的影响。 #include linux/module.h #include linux/kernel.h #include linux/init.h #include linux/static_key.hDEFINE_STATIC_KEY_FALSE(key);void func(int a){if (static_branch_unlikely(key)) { printk(my_module: Feature is enabled\n);} else {printk(my_module: Feature is disabled\n);} }static int __init my_module_init(void) {pr_info(my_module: Module loaded\n);int a 1;func(a);static_branch_enable(key);func(a);return 0; }static void __exit my_module_exit(void) {pr_info(my_module: Module unloaded\n); }module_init(my_module_init); module_exit(my_module_exit);MODULE_LICENSE(GPL); MODULE_AUTHOR(Your Name); MODULE_DESCRIPTION(Sample Kernel Module with Static Key);func汇编代码如下 0000000000000000 func:0: a9bf7bfd stp x29, x30, [sp, #-16]!4: 910003fd mov x29, sp8: d503201f nopc: 90000000 adrp x0, 0 func10: 91000000 add x0, x0, #0x014: 94000000 bl 0 printk18: a8c17bfd ldp x29, x30, [sp], #161c: d65f03c0 ret20: 90000000 adrp x0, 0 func24: 91000000 add x0, x0, #0x028: 94000000 bl 0 printk2c: 17fffffb b 18 func0x18func中不适用static-key时汇编代码如下 void func(int a){if (a) { printk(my_module: Feature is enabled\n);} else {printk(my_module: Feature is disabled\n);} }0000000000000000 func:0: a9bf7bfd stp x29, x30, [sp, #-16]!4: 910003fd mov x29, sp8: 340000a0 cbz w0, 1c func0x1cc: 90000000 adrp x0, 0 func10: 91000000 add x0, x0, #0x014: 94000000 bl 0 printk18: 14000004 b 28 func0x281c: 90000000 adrp x0, 0 func20: 91000000 add x0, x0, #0x024: 94000000 bl 0 printk28: a8c17bfd ldp x29, x30, [sp], #162c: d65f03c0 ret对比可以发现在0x8地址处使用static-key编码在编译时将cbz指令替换为了nop指令减少了程序运行时对比次数。 参考链接 Linux内核中的static-key机制Linux内核jump label与static key的原理与示例static-keys.html | 静态键Linux Jump Label/static-key机制详解
http://www.w-s-a.com/news/123353/

相关文章:

  • 湖北荆门建设银行网站wordpress购物模板下载
  • 学ui+wordpress模板北京推广优化
  • 建分类网站得花多少钱深圳设计网站开发
  • 网站集群建设和网站集约化百度商桥怎么绑定网站
  • 青岛模板网站建设价格网络品牌网站建设
  • 网站建设的几大要素网站的做网站的公司
  • 怎么登陆自己的公司网站垂直电商网站建设
  • 温州微网站制作哪里有许昌网站建设哪家最好
  • 中国中小企业网站官网网页制作工具按其制作方式分 可以分为
  • 做资源下载网站违法吗河南企业做网站
  • 网站开发总体功能设计网站建设 北京昌平
  • 辽宁省高等级公路建设局网站书画院网站建设方案
  • 本地生活网站 源码重庆本地网站有哪些
  • 企业网站域名服务器国外html响应式网站
  • 东莞网站建设策划企业网站推广策划方法
  • 网站的图片怎么制作WordPress交互式网站
  • pc网站增加手机站什么专业学网页设计制作
  • 婚庆公司网站模板wordpress用什么框架
  • 高校网站建设的时效性长沙市网站建设
  • 合肥网站建设市场四川建设网官网住房和城乡厅官网官方
  • 天行健君子以自强不息网站建设江西网站做的好的企业文化
  • 建网站内容谷歌搜索引擎优化
  • 网站建设与管理案例教程第三版答案网站建设策划书范文六篇精选
  • 建设工程项目在哪个网站查询实时网站推广的最终目的是
  • 个人网站可以做淘客网站设置的参数
  • 自适应网站制作公司做室内设计通常上的网站
  • 网站建设项目采购公告建设网站公司建网页
  • 自己做网站怎么推广网站建设应该考虑哪些方面
  • 我做的网站手机上不了wordpress插件整站搬家
  • 河南省和建设厅网站首页西安找建网站公司