最好的同步技术是把设计不需要同步的临界资源放在首位,这是一种思维方法,因为每一种显式的同步原语都有不容忽视的性能开销。

最简单也是最重要的同步技术包括把内核变量或数据结构声明为每CPU变量(per-cpu variable)。每CPU变量主要是数据结构的数组,系统的每个CPU对应数组的一个元素。

一个CPU不应该访问与其他CPU对应的数组元素,另外,它可以随意读或修改它自己的元素而不用担心出现竞争条件,因为它是唯一有资格这么做的CPU。但是,这也意味着每CPU变量基本上只能在特殊情况下使用,也就是当它确定在系统的CPU上的数据在逻辑上是独立的时候。

每CPU的数组元素在主存中被排列以使每个数据结构存放在硬件高速缓存的不同行,因此,对每CPU数组的并发访问不会导致高速缓存行的窃用和失效(这种操作会带来昂贵的系统开销)。

虽然每CPU变量为来自不同CPU的并发访问提供保护,但对来自异步函数(中断处理程序和可延迟函数)的访问不提供保护,在这种情况下需要另外的同步技术。

此外,在单处理器和多处理器系统中,内核抢占都可能使每CPU变量产生竞争条件。总的原则是内核控制路径应该在禁用抢占的情况下访问每CPU变量。因为当一个内核控制路径获得了它的每CPU变量本地副本的地址,然后它因被抢占而转移到另外一个CPU上,但仍然引用原来CPU元素的地址,这是非常危险的。

本博,我们介绍一些每CPU方面有用的宏。

1 DEFINE_PER_CPU(type, name)

静态分配一个每CPU数组,数组名为name,结构类型为type:

#define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name

2 per_cpu(name, cpu)

获得一个为用DEFINE_PER_CPU宏为CPU选择的一个每CPU数组元素,CPU由cpu指定,数组名称为name:

#define per_cpu(var, cpu)     (*((void)(cpu), &per_cpu__##var))

3 __get_cpu_var(name)

选择每CPU数组name的本地CPU元素:

#define __get_cpu_var(var)            per_cpu__##var

4 get_cpu_var(name)

先禁用内核抢占,然后在每CPU数组name中,为本地CPU选择元素:

#define get_cpu_var(var) (*({ preempt_disable(); &__get_cpu_var(var); }))

5 put_cpu_var(name)

启用内核抢占(不使用name):

#define put_cpu_var(var) preempt_enable()

6 alloc_percpu(type)

动态分配type类型数据结构的每CPU数组,并返回它的地址:

#define alloc_percpu(type)    ((type *)(__alloc_percpu(sizeof(type))))
static inline void *__alloc_percpu(size_t size)
{
void *ret = kmalloc(size, GFP_KERNEL);
if (ret)
memset(ret, 0, size);
return ret;
}

7 free_percpu(pointer)

释放动态分配的每CPU数组,pointer指示其地址:

static inline void free_percpu(const void *ptr)
{
kfree(ptr);
}

8 per_cpu_ptr(pointer, cpu)

返回每CPU数组中与cpu对应CPU元素地址,pointer给出数组地址:

#define per_cpu_ptr(ptr, cpu) ({ (void)(cpu); (ptr); })

from:http://blog.csdn.net/yunsongice/article/details/5605239

每CPU变量的更多相关文章

  1. linux内核中的每cpu变量

    一.linux中的每cpu变量 看linux内核代码的时候,会发现大量的per_cpu(name, cpu),get_cpu_var(name)等出现cpu字眼的语句.从语句的意思可以看出是要使用与当 ...

  2. linux内核同步之每CPU变量、原子操作、内存屏障、自旋锁【转】

    转自:http://blog.csdn.net/goodluckwhh/article/details/9005585 版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 一每 ...

  3. linux:cpu 每-CPU 的变量

    每-CPU 的变量 每-CPU 变量是一个有趣的 2.6 内核的特性. 当你创建一个每-CPU变量, 系统中每个处理器获得它自己的这个变量拷贝. 这个可能象一个想做的奇怪的事情, 但是它有自己的优点. ...

  4. linux 每-CPU 的变量

    每-CPU 变量是一个有趣的 2.6 内核的特性. 当你创建一个每-CPU 变量, 系统中每个处理 器获得它自己的这个变量拷贝. 这个可能象一个想做的奇怪的事情, 但是它有自己的优点. 存取每-CPU ...

  5. Intel 80x86 Linux Kernel Interrupt(中断)、Interrupt Priority、Interrupt nesting、Prohibit Things Whthin CPU In The Interrupt Off State

    目录 . 引言 . Linux 中断的概念 . 中断处理流程 . Linux 中断相关的源代码分析 . Linux 硬件中断 . Linux 软中断 . 中断优先级 . CPU在关中断状态下编程要注意 ...

  6. Linux内核同步机制之(二):Per-CPU变量

    转自:http://www.wowotech.net/linux_kenrel/per-cpu.html 一.源由:为何引入Per-CPU变量? 1.lock bus带来的性能问题 在ARM平台上,A ...

  7. xv6中存储cpu和进程信息的技巧

    xv6是一个支持多处理器的Unix-like操作系统, 近日阅读源码时发现xv6在记录当前CPU和进程状态时非常tricky 首先,上代码: extern struct cpu cpus[NCPU]; ...

  8. 激活第一个CPU

    回到start_kernel,559行,boot_cpu_init函数,跟start_kernel位于同一文件: 494static void __init boot_cpu_init(void) 4 ...

  9. per-CPU变量

    为什么需要per-CPU变量 假设系统中有4个cpu, 同时有一个变量在各个CPU之间是共享的,每个cpu都有访问该变量的权限. 当cpu1在改变变量v的值的时候,cpu2也需要改变变量v的值.这时候 ...

随机推荐

  1. Hadoop 3.x 新特性剖析系列1

    1.概述 目前从Hadoop官网的Wiki来看,稳定版本已经发行到Hadoop2.9.0,最新版本为Hadoop3.1.0,查阅JIRA,社区已经着手迭代Hadoop3.2.0.那么,今天笔者就带着大 ...

  2. 基于gin框架和jwt-go中间件实现小程序用户登陆和token验证

    本文核心内容是利用jwt-go中间件来开发golang webapi用户登陆模块的token下发和验证,小程序登陆功能只是一个切入点,这套逻辑同样适用于其他客户端的登陆处理. 小程序登陆逻辑 小程序的 ...

  3. 福利:100G Java全套学习视频免费送了

    嗯 是的 众所周知 java工会自开办以来 一直致力于分享一些 java技术总结 学习方法..等等等 所以 从我做这个公众号以来 我的手机就没有消停过一天 因为 每天都有很多粉丝问我 "您好 ...

  4. ios开发-日期处理(类似朋友圈,微博等的发送时间)

    ios开发中,我们经常要处理从服务器获取的时间.类似朋友圈,微博这些应用.我们经常可以看到“刚刚”,“31分钟前发表”,“昨天5点”,之类的字样. 当时我们从服务器端获取的都是那条朋友圈信息,或者微博 ...

  5. Python数据类型和数据操作

    python数据类型有:int,float,string,boolean类型.其中string类型是不可变变量,用string定义的变量称为不可变变量,该变量的值不能修改. 下面介绍python中的l ...

  6. 机器学习基石:07 The VC Dimension

    当N大于等于2,k大于等于3时, 易得:mH(N)被Nk-1给bound住. VC维:最小断点值-1/H能shatter的最大k值. 这里的k指的是存在k个输入能被H给shatter,不是任意k个输入 ...

  7. pwd

    显示当前在文件系统里的确切位置 注: 系统根目录是/ 用户主目录是/home/用户名 对于root用户,用户主目录为/root

  8. Redis常用命令--Lists

    List是一个双向链表,按照插入顺序排序,可以添加一个元素到头部或者尾部.当对一个空key执行插入操作的时候会创建一个新表. 如果要清空列表,则会杀出对应的key空间. 在List中保存了头节点和未节 ...

  9. [HAOI 2011]Problem c

    Description 给n个人安排座位,先给每个人一个1~n的编号,设第i个人的编号为ai(不同人的编号可以相同),接着从第一个人开始,大家依次入座,第i个人来了以后尝试坐到ai,如果ai被占据了, ...

  10. [HNOI2013]比赛

    题目描述 沫沫非常喜欢看足球赛,但因为沉迷于射箭游戏,错过了最近的一次足球联赛.此次联 赛共N支球队参加,比赛规则如下: (1) 每两支球队之间踢一场比赛. (2) 若平局,两支球队各得1分. (3) ...