每-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 变量在你自己的代码, 你应当尽量使它们小.

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

  1. linux:CPU私有变量(per-CPU变量)

    一.简介2.6内核上一个新的特性就是per-CPU变量.顾名思义,就是每个处理器上有此变量的一个副本.per-CPU的最大优点就是,对它的访问几乎不需要锁,因为每个CPU都在自己的副本上工作.task ...

  2. linux:cpu 每-CPU 的变量

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

  3. Linux内核同步 - Per-CPU变量

    一.源由:为何引入Per-CPU变量? 1.lock bus带来的性能问题 在ARM平台上,ARMv6之前,SWP和SWPB指令被用来支持对shared memory的访问: SWP <Rt&g ...

  4. LINUX内核CPU负载均衡机制【转】

    转自:http://oenhan.com/cpu-load-balance 还是神奇的进程调度问题引发的,参看Linux进程组调度机制分析,组调度机制是看清楚了,发现在重启过程中,很多内核调用栈阻塞在 ...

  5. linux定时任务crond export变量问题

    linux定时任务crond export变量问题 1)我写了一个重启resin的脚本,由于业务原因,需要定时在某一个时间重启下resin服务器,于是就在 crontab里配置了如下内容: 50 17 ...

  6. linux配置java环境变量(详细)

    linux配置java环境变量(详细) 本文完全引用自: http://www.cnblogs.com/samcn/archive/2011/03/16/1986248.html 一. 解压安装jdk ...

  7. linux配置java环境变量

    linux配置java环境变量(详细) 一. 解压安装jdk 在shell终端下进入jdk-6u14-linux-i586.bin文件所在目录, 执行命令 ./jdk-6u14-linux-i586. ...

  8. Linux 查看CPU,内存,硬盘 !转

    Linux 查看CPU,内存,硬盘 本文转自:http://hi.baidu.com/mumachuntian/item/a401368dbe8a66cab07154e8 1 查看CPU 1.1 查看 ...

  9. Linux里设置环境变量的方法(export PATH)

    1.动态库路径的设置 Linux下调用动态库和windows不一样.linux 可执行程序是靠配置文件去读取路径的,因此有些时候需要设置路径 具体操作如下 export LD_LIBRARY_PATH ...

随机推荐

  1. jdbc连接数据库的步骤(转载)

    http://hzy3774.iteye.com/blog/1689525   1.加载JDBC驱动程序: 在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过jav ...

  2. android performance

    https://developer.android.com/studio/profile/systrace.html http://www.milan100.com/article/show/1544 ...

  3. Linux中的库

    一.基本概念 1.1.什么是库        在 windows 平台和 linux 平台下都大量存在着库. 本质上来说库是一种可执行的二进制代码(但不可以独立执行),可以被操作系统载入内存执行. 由 ...

  4. Convert Sorted Array to Binary Search Tree转换成平衡二查搜索树

    Given an array where elements are sorted in ascending order, convert it to a height balanced BST. 二分 ...

  5. 【调试】Visual Studio 调试小技巧(2)-从查看窗口得到更多信息(转载)

    在使用Visual Studio开发调试程序时,我们经常需要打开查看窗口(Watch)来分析变量.有时在查看窗口显示的内容不是很直观.为了能从查看窗口的变量中得到更多的信息,我们需要一些小的技巧.下面 ...

  6. Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试

    原文:Introduction to 3D Game Programming with DirectX 12 学习笔记之 --- 第十一章:模板测试 代码工程地址: https://github.co ...

  7. phpexcel使用说明2

      转自:http://serisboy.iteye.com/blog/1928139 首先到phpexcel官网上下载最新的phpexcel类,下周解压缩一个classes文件夹,里面包含了PHPE ...

  8. Atcoder Tenka1 Programmer Contest D: IntegerotS 【思维题,位运算】

    http://tenka1-2017.contest.atcoder.jp/tasks/tenka1_2017_d 给定N,K和A1...AN,B1...BN,选取若干个Ai使它们的或运算值小于等于K ...

  9. HZOJ 赤(CF739E Gosha is hunting)

    本来没有打算写题解的,时间有点紧.但是这个wqs二分看了好久才明白还是写点东西吧. 题解就直接粘dg的了: 赤(red) 本题来自codeforces 739E,加大了数据范围. 首先对一只猫不会扔两 ...

  10. LeetCode67 Add Binary

    题目: Given two binary strings, return their sum (also a binary string). (Easy) For example,a = " ...