关闭

static-key机制

533人阅读 评论(0) 收藏 举报
分类:
内核的static-key用来优化if-else频繁判断的问题.
如何使用:
#define DEFINE_STATIC_KEY_FALSE(name)    \
    struct static_key_false name = STATIC_KEY_FALSE_INIT
一般使用DEFINE_STATIC_KEY_FALSE 定义条件不成立的case,用DECLARE_STATIC_KEY_TRUE定义条件成立的case
#define DEFINE_STATIC_KEY_TRUE(name)    \
    struct static_key_true name = STATIC_KEY_TRUE_INIT


例如kernel/sched/core.c中的定义
DEFINE_STATIC_KEY_FALSE(sched_numa_balancing);
实际判读的时候,可以用static_branch_likely和static_branch_unlikely 来判断定义的这个变量表达的条件是否成立.
if (static_branch_likely(&sched_numa_balancing))
    return;
原理分析:
首先看定义struct static_key_false name = STATIC_KEY_FALSE_INIT
static_key_false 结构体的定义如下:
#ifdef HAVE_JUMP_LABEL

struct static_key {
    atomic_t enabled;
/* Set lsb bit to 1 if branch is default true, 0 ot */
    struct jump_entry *entries;
#ifdef CONFIG_MODULES
    struct static_key_mod *next;
#endif
};

#else
struct static_key {
    atomic_t enabled;
};
#endif    /* HAVE_JUMP_LABEL */
可见如果没有定义HAVE_JUMP_LABEL,则static_key 退化成atomic变量
#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.

#ifdef HAVE_JUMP_LABEL

#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();                \
    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();                \
    branch;                                    \
})

#else /* !HAVE_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 /* HAVE_JUMP_LABEL */
可见同样依赖HAVE_JUMP_LABEL。如果没有定义的话,直接退化成likely和unlikely
static_branch_likely 和 static_branch_unlikely 主要是调用arch_static_branch和arch_static_branch_jump 来判断。arch_static_branch表示条件成立,继续执行
例如if (static_branch_likely(&sched_numa_balancing))
    return;
就直接return了
而arch_static_branch_jump 表示条件不成立,执行跳转。
使用这种机制比likely和unlikely的另外一个好处就是可以动态改变执行的条件
#define static_branch_enable(x)        static_key_enable(&(x)->key)
#define static_branch_disable(x)    static_key_disable(&(x)->key)
调用static_key_slow_dec 来使key加1
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_key_slow_inc 来使key减1
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_branch_enable和 static_branch_disable 外,还可以通过static_branch_inc 是判断条件加1,从而是条件成立.反之依然.
#define static_branch_inc(x)        static_key_slow_inc(&(x)->key)
#define static_branch_dec(x)        static_key_slow_dec(&(x)->key)
总的来说static-key 机制比like/unlikely 灵活,推荐使用。



0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

java static块执行机制

java 类运行的机制及static执行机制
  • sunjinshengli
  • sunjinshengli
  • 2017-04-19 00:27
  • 214

内核的static-key机制

内核的static-key
  • phenix_lord
  • phenix_lord
  • 2015-10-18 22:33
  • 1168

内核的static-key机制

内核的static-key
  • phenix_lord
  • phenix_lord
  • 2015-10-18 22:33
  • 1168

redis key的过期机制

本文为阅读 http://www.redis.io/commands/expire 做的一些记录总结 redis是一个 高性能的key-value数据库.我们可以对其中的key设置一个过期时...
  • u013790419
  • u013790419
  • 2015-09-06 11:27
  • 3704

说说PHP的autoLoad自动加载机制

__autoload的使用方法1:  最经常使用的就是这种方法,根据类名,找出类文件,然后require_once function __autoload($class_name) { $path...
  • sinat_34990639
  • sinat_34990639
  • 2016-09-02 12:18
  • 1297

About a key word Static

[编程技术及协议]About a key word Static  lentil 发表于 2007-8-10 21:54:00 1. static 变量 静态...
  • liubin15989534919
  • liubin15989534919
  • 2011-09-30 13:28
  • 290

c and c++ static key word

C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说明static在类中的作用。 一、面向过程设计中的s...
  • sony315
  • sony315
  • 2011-08-23 10:19
  • 343

【ecstore深思录】细谈其引入的KV机制(key-value)

一、kv是个什么鬼: kv存储机制(key-value-store)是商派研发的ecos框架解决大数据存储的一种优化方式。对memcached、systemfile/flare等进行封装把不常变...
  • a5485899
  • a5485899
  • 2017-01-05 14:08
  • 823

redis的key的过期机制

redis是一个 高性能的key-value数据库.我们可以对其中的key设置一个过期时间,相关命令如下: 1.在创建一个key value 的时候同时设置过期时间 比如: set key...
  • walxiaosage
  • walxiaosage
  • 2015-09-20 20:38
  • 270

Key-Value Observing机制 学习

知识点介绍 Key-Value Observing (简写为KVO):当指定的对象的属性被修改了,允许对象接受到通知的机制。每次指定的被观察对象的属性被修改的时候,KVO都会自动的去通知相应的观察者...
  • lkeplei
  • lkeplei
  • 2014-08-12 14:08
  • 251
    个人资料
    • 访问:258015次
    • 积分:12808
    • 等级:
    • 排名:第1247名
    • 原创:1062篇
    • 转载:0篇
    • 译文:11篇
    • 评论:9条
    最新评论