程序员的“纪律性”(《程序员杂志》署名文章)
作者:travelhop 发布于:2014-11-18 10:46 分类:技术漫谈
多问几个为什么一定要这样和为什么不那样,对一个年轻人,尤其对一个有技术追求的年轻人永远有好处。
单纯从项目开发的效率来讲,团队里面有这样的软件多面手,有能够提出这样想法的人,比一个外行领导者对于开发者纪律性的要求要有意义,也有效的多。
Linux内核同步机制之(三):memory barrier
作者:linuxer 发布于:2014-11-14 19:20 分类:内核同步机制
我记得以前上学的时候大家经常说的一个词汇叫做所见即所得,有些编程工具是所见即所得的,给程序员带来极大的方便。对于一个c程序员,我们的编写的 代码能所见即所得吗?我们看到的c程序的逻辑是否就是最后CPU运行的结果呢?很遗憾,不是,我们的“所见”和最后的执行结果隔着:
1、编译器
2、CPU取指执行
编 译器将符合人类思考的逻辑(c代码)翻译成了符合CPU运算规则的汇编指令,编译器了解底层CPU的思维模式,因此,它可以在将c翻译成汇编的时候进行优 化(例如内存访问指令的重新排序),让产出的汇编指令在CPU上运行的时候更快。然而,这种优化产出的结果未必符合程序员原始的逻辑,因此,作为程序员, 作为c程序员,必须有能力了解编译器的行为,并在通过内嵌在c代码中的memory barrier来指导编译器的优化行为(这种memory barrier又叫做优化屏障,Optimization barrier),让编译器产出即高效,又逻辑正确的代码。
CPU的核心思想就 是取指执行,对于in-order的单核CPU,并且没有cache(这种CPU在现实世界中还存在吗?),汇编指令的取指和执行是严格按照顺序进行的, 也就是说,汇编指令就是所见即所得的,汇编指令的逻辑被严格的被CPU执行。然而,随着计算机系统越来越复杂(多核、cache、 superscalar、out-of-order),使用汇编指令这样贴近处理器的语言也无法保证其被CPU执行的结果的一致性,从而需要程序员(看, 人还是最不可以替代的)告知CPU如何保证逻辑正确。
综上所述,memory barrier是一种保证内存访问顺序的一种方法,让系统中的HW block(各个cpu、DMA controler、device等)对内存有一致性的视角。
Linux PM domain framework(1)_概述和使用流程
作者:wowo 发布于:2014-11-13 22:09 分类:电源管理子系统
在复杂的片上系统(SOC)中,设计者一般会将系统的供电分为多个独立的block,这称作电源域(Power Domain),这样做有很多好处,例如:
1)将不同功能模块的供电分开,减小相互之间的干扰(如模拟和数字分开)。
2)不同功能所需的电压大小不同:小电压能量损耗低,但对信号质量的要求较高;大电压能量损耗高,对信号质量的要求较低。因此可以根据实际情况,使用不同的电压供电,例如CPU core只需1.2v左右即可,而大部分的I/O则需要3.3v左右。
3)系统运行的大部分时间,并不需要所有模块都处于power on状态,因此可以通过关闭不工作模块的供电,将它们的耗电降为最低。
4)等等
虽然电源域的好处多多,却不是越多越好,因为划分电源域是需要成本的(需要在PMU中使用模拟电路完成,包括金钱成本和空间成本)。因此,大多数系统会根据功能,设置有限的几个电源域,例如:CPU core(1、2、3…);GPU;NAND;DDR;USB;Display;Codec;等等。
这种设计引出一个问题:存在多个模块共用一个电源域的情况。因而要求在对模块power on/off的时候,考虑power共用的情况:只要一个模块工作,就要power on;直到所有模块停止工作,才能power off。
Kernel的PM domain framework(位于drivers/base/power/domain.c中),提供了管理和使用系统power domain的统一方法,在解决上面提到的问题的同时,结合kernel的suspend、runtime pm、clock framework等机制,以非常巧妙、灵活的方式,管理系统供电,以达到高效、节能的目的。
同样,作为一个framework,我们可以从三个角度分析:使用者(consumer)的角度;提供者(provider)的角度;内部实现。具体如下。
注:本文的linux kernel版本为3.18-rc4。一般情况下,对于那些相对稳定的framework,蜗蜗不会说明文章所使用的kernel版本,但本文是个例外,因为PM domain很多方便、易用的patch,只能在最新版本(当前为3.18-rc4)kernel上才能看到。
标签: Linux PM 电源管理 framework domain
我眼中的可穿戴设备
作者:travelhop 发布于:2014-11-5 14:55 分类:技术漫谈
可穿戴设备,一个现在非常火热的话题,它是很多创业者眼中河滩上的宝钻、沙漠中的绿洲、戈壁滩上的金球球……
作者从一个曾经的创业者、同时也是一个技术人员的观点来看可穿戴设备的市场现状,提出了自己的想法。
技术寓言神马的,爱信不信,信也不一定灵。不过看待滚滚红尘中的一波未平一波又起的热潮,作者的冷静值得借鉴……
新技能get: 订阅Linux内核邮件列表
作者:wowo 发布于:2014-11-4 22:37 分类:Linux应用技巧
本文给小伙伴们分享一下怎么订阅Linux内核邮件列表(Linux kernel mailing list,LKML)。标签: Linux Kernel mailing list LKML
linux kernel的中断子系统之(八):softirq
作者:linuxer 发布于:2014-10-24 11:53 分类:中断子系统
对于中断处理而言,linux将其分成了两个部分,一个叫做中断handler(top half),是全程关闭中断的,另外一部分是deferable task(bottom half),属于不那么紧急需要处理的事情。在执行bottom half的时候,是开中断的。有多种bottom half的机制,例如:softirq、tasklet、workqueue或是直接创建一个kernel thread来执行bottom half(这在旧的kernel驱动中常见,现在,一个理智的driver厂商是不会这么做的)。本文主要讨论softirq机制。由于tasklet是 基于softirq的,因此本文也会提及tasklet,但主要是从需求层面考虑,不会涉及其具体的代码实现。
在普通的驱动中一般是不会用 到softirq,但是由于驱动经常使用的tasklet是基于softirq的,因此,了解softirq机制有助于撰写更优雅的driver。 softirq不能动态分配,都是静态定义的。内核已经定义了若干种softirq number,例如网络数据的收发、block设备的数据访问(数据量大,通信带宽高),timer的deferable task(时间方面要求高)。本文的第二章讨论了softirq和tasklet这两种机制有何不同,分别适用于什么样的场景。第三章描述了一些 context的概念,这是要理解后续内容的基础。第四章是进入softirq的实现,对比hard irq来解析soft irq的注册、触发,调度的过程。
注:本文中的linux kernel的版本是3.14
防冲突机制介绍
作者:cherishui 发布于:2014-10-24 11:35 分类:基础技术
本文介绍了通讯领域中的两种防冲突机制,CSMA/CD和CSMA/CA.Linux common clock framework(2)_clock provider
作者:wowo 发布于:2014-10-23 23:49 分类:电源管理子系统
本文接上篇文章,从clock driver的角度,分析怎么借助common clock framework管理系统的时钟资源。换句话说,就是怎么编写一个clock driver。
由于kernel称clock driver为clock provider(相应的,clock的使用者为clock consumer),因此本文遵循这个规则,统一以clock provider命名。
标签: Linux framework clock provider dts
arm64 linux移植
作者:forion 发布于:2014-10-23 17:02
arm64大潮来势汹汹,不知道大家有没有在搞64位cpu呢?
arm64 linux 只支持device tree了,大家要努力学好dt啦。可以去参考楼主之前的dt文章。
arm64 架构已经有很大的改变啦,不知道楼主什么时候给大家普及呢?哈哈。
Porting to ARM 64-bit.pdf
32-bit to 64-bit portingv3.pdf上面两篇pdf在网上可以找到,可以初步的了解aarch32与aarch64 porting注意事项。
linux内核同步
作者:dashijian 发布于:2014-10-21 16:41
同步就是避免并发和防止竞争条件。有关临界区的例子我就不举了,随便一本操作系统的书上都有。锁机制的提出也算解决了一些问题,我们待会再说,现在只要知道锁的使用是自愿的,非强制的。linux自身也提供了几种不同的锁机制,区别主要在于当锁被争用时,有些会简单地执行等待,而有些锁会使当前任务睡眠直到锁可用为止,这个后面细说。真正的困难在于发现并辨认出真正需要共享的数据和相应的共享区。先来说一些感性的话:大多数内核数据结构都需要加锁,如果有其他执行线程可以访问这些数据,那么就给这些数据加上某种形式的锁。如果任何其他什么东西能看到它,那么就要锁住它。简而言之,几乎访问所有的内核全局变量和共享数据都需要某种形式的同步方法。有关加锁的细节,在嵌套的锁时,要保证以相同的顺序获取锁,不要重复请求同一个锁,释放时,最好还是以获得锁的相反顺序来释放锁。加锁的粒度用来描述加锁保护的数据规模。接下来就开始讨论真正的同步方法:
1.原子操作。就是指执行过程不被打断的操作,是 不能够被分割的指令。关于这个linux内核提供了两组原子操作接口:原子整数操作和原子位操作。好,先来说说这个原子整数操作。针对整数的原子操作只能对atomic_t类型的数据进行处理。需要说明的是,尽管linux支持的所有机器上的整形数据都是32位的,但是使用atomic_t的代码只能将该类型的数据当作24位来用,原因就不说了。使用原子操作需要的声明在asm/atomic.h中。原子整数操作列表如下;
对应于原子整数操作,还有一种原子操作就是原子位操作,它们是与体系结构相关的操作,定义在文件<asm/bitops.h>,它是对普通的内存地址进行操作的。它的参数是一个指针和一个位号,第0位是给定地址的最低有效位。这里没有想atomic_t一样的数据结构,只要指针指向任何希望的数据,就可以进行操作。原子位操作函数列表如下:
同时,内核还提供了一组与上述操作对应的非原子位函数,操作完全相同,不同在于不保证原子性且名字前缀多了两个下划线,例如与test_bit()对应的非原子形式是__test_bit().如果不需要原子操作,这时这些函数的执行效率可能更高。内核还提供了两个函数用来从指定的地址开始搜索第一个被设置(或未被设置)的位:
功能
最新评论
文章分类
随机文章
文章存档
- 2024年2月(1)
- 2023年5月(1)
- 2022年10月(1)
- 2022年8月(1)
- 2022年6月(1)
- 2022年5月(1)
- 2022年4月(2)
- 2022年2月(2)
- 2021年12月(1)
- 2021年11月(5)
- 2021年7月(1)
- 2021年6月(1)
- 2021年5月(3)
- 2020年3月(3)
- 2020年2月(2)
- 2020年1月(3)
- 2019年12月(3)
- 2019年5月(4)
- 2019年3月(1)
- 2019年1月(3)
- 2018年12月(2)
- 2018年11月(1)
- 2018年10月(2)
- 2018年8月(1)
- 2018年6月(1)
- 2018年5月(1)
- 2018年4月(7)
- 2018年2月(4)
- 2018年1月(5)
- 2017年12月(2)
- 2017年11月(2)
- 2017年10月(1)
- 2017年9月(5)
- 2017年8月(4)
- 2017年7月(4)
- 2017年6月(3)
- 2017年5月(3)
- 2017年4月(1)
- 2017年3月(8)
- 2017年2月(6)
- 2017年1月(5)
- 2016年12月(6)
- 2016年11月(11)
- 2016年10月(9)
- 2016年9月(6)
- 2016年8月(9)
- 2016年7月(5)
- 2016年6月(8)
- 2016年5月(8)
- 2016年4月(7)
- 2016年3月(5)
- 2016年2月(5)
- 2016年1月(6)
- 2015年12月(6)
- 2015年11月(9)
- 2015年10月(9)
- 2015年9月(4)
- 2015年8月(3)
- 2015年7月(7)
- 2015年6月(3)
- 2015年5月(6)
- 2015年4月(9)
- 2015年3月(9)
- 2015年2月(6)
- 2015年1月(6)
- 2014年12月(17)
- 2014年11月(8)
- 2014年10月(9)
- 2014年9月(7)
- 2014年8月(12)
- 2014年7月(6)
- 2014年6月(6)
- 2014年5月(9)
- 2014年4月(9)
- 2014年3月(7)
- 2014年2月(3)
- 2014年1月(4)