每-CPU 的变量

每-CPU 变量是一个有趣的 2.6 内核的特性. 当你创建一个每-CPU变量, 系统中每个处理器获得它自己的这个变量拷贝. 这个可能象一个想做的奇怪的事情, 但是它有自己的优点. 存取每-CPU变量不需要(几乎)加锁, 因为每个处理器使用它自己的拷贝. 每-CPU 变量也可存在于它们各自的处理器缓存中, 这样对于频繁更新的量子带来了显著的更好性能.

一个每-CPU变量的好的使用例子可在网络子系统中找到. 内核维护无结尾的计数器来跟踪有每种报文类型有多少被接收; 这些计数器可能每秒几千次地被更新. 不去处理缓存和加锁问题, 网络开发者将统计计数器放进每-CPU变量. 现在更新是无锁并且快的. 在很少的机会用户空间请求看到计数器的值, 相加每个处理器的版本并且返回总数是一个简单的事情.

每-CPU变量的声明可在 <linux/percpu.h> 中找到. 为在编译时间创建一个每-CPU变量, 使用这个宏定义:

DEFINE_PER_CPU(type, name);

如果这个变量(称为 name 的)是一个数组, 包含这个类型的维数信息. 因此, 一个有 3 个整数的每-CPU 数组应当被创建使用:

DEFINE_PER_CPU(int[3], my_percpu_array);

每-CPU变量几乎不必使用明确的加锁来操作. 记住 2.6 内核是可抢占的; 对于一个处理器, 在修改一个每-CPU变量的临界区中不应当被抢占. 并且如果你的进程在对一个每-CPU变量存取时将, 要被移动到另一个处理器上, 也不好. 因为这个原因, 你必须显式使用 get_cpu_var 宏来存取当前处理器的给定变量拷贝, 并且当你完成时调用 put_cpu_var. 对 get_cpu_var 的调用返回一个 lvalue 给当前处理器的变量版本并且禁止抢占. 因为一个 lvalue 被返回, 它可被赋值给或者直接操作. 例如, 一个网络代码中的计数器时使用这 2 个语句来递增的:

get_cpu_var(sockets_in_use)++;
put_cpu_var(sockets_in_use);

你可以存取另一个处理器的变量拷贝, 使用:

per_cpu(variable, int cpu_id);

如果你编写使处理器涉及到对方的每-CPU变量的代码, 你, 当然, 一定要实现一个加锁机制来使存取安全.

动态分配每-CPU变量也是可能的. 这些变量可被分配, 使用:

void *alloc_percpu(type);
void *__alloc_percpu(size_t size, size_t align);

在大部分情况, alloc_percpu 做的不错; 你可以调用 __alloc_percpu 在需要一个特别的对齐的情况下. 在任一情况下, 一个 每-CPU 变量可以使用 free_percpu 被返回给系统. 存取一个动态分配的每-CPU变量通过 per_cpu_ptr 来完成:

per_cpu_ptr(void *per_cpu_var, int cpu_id);

这个宏返回一个指针指向 per_cpu_var 对应于给定 cpu_id 的版本. 如果你在简单地读另一个 CPU 的这个变量的版本, 你可以解引用这个指针并且用它来完成. 如果, 但是, 你在操作当前处理器的版本, 你可能需要首先保证你不能被移出那个处理器. 如果你存取这个每-CPU变量的全部都持有一个自旋锁, 万事大吉. 常常, 但是, 你需要使用 get_cpu 来阻止在使用变量时的抢占. 因此, 使用动态每-CPU变量的代码会看来如此:

int cpu;
cpu = get_cpu()
ptr = per_cpu_ptr(per_cpu_var, cpu);
/* work with ptr */
put_cpu();

当使用编译时每-CPU 变量时, get_cpu_var 和 put_cpu_var 宏来照看这些细节. 动态每-CPU变量需要更多的显式的保护.

每-CPU变量能够输出给每个模块, 但是你必须使用一个特殊的宏版本:

EXPORT_PER_CPU_SYMBOL(per_cpu_var);
EXPORT_PER_CPU_SYMBOL_GPL(per_cpu_var);

为在一个模块内存取这样一个变量, 声明它, 使用:

DECLARE_PER_CPU(type, name);

DECLARE_PER_CPU 的使用(不是 DEFINE_PER_CPU)告知编译器进行一个外部引用.

如果你想使用每-CPU变量来创建一个简单的整数计数器, 看一下在 <linux/percpu_counter.h> 中的现成的实现. 最后, 注意一些体系有有限数量的地址空间变量给每-CPU变量. 如果你创建每-CPU变量在你自己的代码, 你应当尽量使它们小.

from:http://oss.org.cn/kernel-book/ldd3/ch08s04.html

linux:cpu 每-CPU 的变量的更多相关文章

  1. linux概念之cpu分析

    http://ilinuxkernel.com/?cat=4 Linux CPU占用率原理与精确度分析1  CPU占用率计算原理在Linux/Unix 下,CPU 利用率分为用户态.系统态和空闲态,分 ...

  2. Linux CPU Hotplug CPU热插拔

    http://blog.chinaunix.net/uid-15007890-id-106930.html   CPU hotplug Support in Linux(tm) Kernel Linu ...

  3. 全面了解 Linux 服务器 - 1. 查看 Linux 服务器的 CPU 详细情况

    1. 查看 Linux 服务器的 CPU 详细情况 判断依据: 具有相同的 core id 的 CPU 是同意个 core 超线程. 具有相同的 physical id 的 CPU 是同一个 CPU ...

  4. 查看数量linux下查看cpu物理个数和逻辑个数

    首先声明,我是一个菜鸟.一下文章中出现技术误导情况盖不负责 hadoop@chw-desktop3:~$ cat /proc/cpuinfo processor : 0 vendor_id : Gen ...

  5. Linux下区分物理CPU、逻辑CPU和CPU核数

    ㈠ 概念           ① 物理CPU                             实际Server中插槽上的CPU个数              物理cpu数量,可以数不重复的 p ...

  6. linux性能优化cpu 磁盘IO MEM

    系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上 ...

  7. linux下查看cpu物理个数和逻辑个数 - chw1989的专栏 - 博客频道 - CSDN.NET

    body { font-family: 微软雅黑,"Microsoft YaHei", Georgia,Helvetica,Arial,sans-serif,宋体, PMingLi ...

  8. linux Java项目CPU内存占用高故障排查

    linux Java项目CPU内存占用高故障排查 top -Hp 进程号 显示进程中每个线程信息,配合jstack定位java线程运行情况 # 线程详情 jstack 线程PID # 查看堆内存中的对 ...

  9. linux下的CPU、内存、IO、网络的压力测试

    linux下的CPU.内存.IO.网络的压力测试  要远程测试其实很简单了,把结果放到一个微服务里直接在web里查看就可以了,或者同步到其他服务器上 一.对CPU进行简单测试: 1.通过bc命令计算特 ...

  10. 关于linux系统CPU篇--->CPU使用率升高

    1.CPU使用率为单位时间内CPU使用情况的统计,以百分比的方式展示. LINUX作为一个多任务操作系统,将每个CPU的时间划分为很短的时间片,再通过调度器轮流分配给各个任务使用,因此造成多任务同时运 ...

随机推荐

  1. h5视频和音频 -2018/04/16

    HTML5 规定了一种通过 video 元素来包含视频的标准方法. 当前video元素支持的三种视频格式: (1)Ogg 带有Theora视频编码和Vorbis音频编码的ogg文件 (2)MPEG4带 ...

  2. Hibernate 学习之Query查询(HQL查询)

    package com.itcloud.test; import com.itcloud.pojo.Dept; import org.hibernate.Session; import org.hib ...

  3. [LeetCode] Split Array with Equal Sum 分割数组成和相同的子数组

    Given an array with n integers, you need to find if there are triplets (i, j, k) which satisfies fol ...

  4. 计蒜客NOIP模拟赛4 D1T3 小X的佛光

    小 X 是远近闻名的学佛,平日里最喜欢做的事就是蒸发学水. 小 X 所在的城市 X 城是一个含有 N 个节点的无向图,同时,由于 X 国是一个发展中国家,为了节约城市建设的经费,X 国首相在建造 X ...

  5. 【bzoj4011 hnoi2015】落忆枫音

    题目描述 「恒逸,你相信灵魂的存在吗?」 郭恒逸和姚枫茜漫步在枫音乡的街道上.望着漫天飞舞的红枫,枫茜突然问出这样一个问题. 「相信吧.不然我们是什么,一团肉吗?要不是有灵魂......我们也不可能再 ...

  6. [bzoj1063][Noi2008]道路设计

    来自FallDream的博客,未经允许,请勿转载,谢谢. Z国坐落于遥远而又神奇的东方半岛上,在小Z的统治时代公路成为这里主要的交通手段.Z国共有n座城市,一些城市之间由双向的公路所连接.非常神奇的是 ...

  7. [Helvetic Coding Contest 2017 online mirror]

    来自FallDream的博客,未经允许,请勿转载,谢谢, 第一次在cf上打acm...和同校大佬组队打 总共15题,比较鬼畜,最后勉强过了10题. AB一样的题目,不同数据范围,一起讲吧 你有一个背包 ...

  8. bzoj1293[SCOI2009]生日礼物 尺取法

    1293: [SCOI2009]生日礼物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2838  Solved: 1547[Submit][Stat ...

  9. APIO2017 懵逼记

    Day -1: 移步http://www.cnblogs.com/juruolty/p/6854795.html Day 0: CTSC铁牌后,下一个就是APIO了. lmy,sxy,cxc,lh过来 ...

  10. Thinkphp中的U函数(Thinkphp3.2.3版本)

    U函数的作用是根据当前的URL设置生成对应的URL地址,使用U函数可以确保项目在移植过程中不受环境的影响. U方法的定义规则如下(方括号内参数根据实际应用决定): U('地址表达式',['参数'],[ ...