2009年11月7日星期六
Linux不需要碎片整理
http://geekblog.oneandoneis2.org/index.php/2006/08/17/why_doesn_t_linux_need_defragmenting
http://geekblog.oneandoneis2.org/index.php/2007/01/04/why_deleting_just_isn_t_enough
http://www.linux.org/docs/ldp/howto/Partition/appendix.html#fragmentation
2009年11月5日星期四
terms--trap,exception,system call,interrupt
Trap: Denote a programmer initiated and expected transfer of control to a special handler routine.In many respects, a trap is nothing more than a specialized subroutine call. Many texts refer to traps as software interrupts.
exception: Exceptions are illegal program actions that generate an interrupt. Examples of illegal programs actions include divide by zero, attempt to access memory outside segment bounds, and so on.
system call: With a system call a user program can ask for an operating system service.System calls provide the interface between a process and the operating system.
Interrupt: Interrupts are generated by hardware devices that need attention of the operating system. For example, a clock chip may generate an interrupt every 100 msec to allow the kernel to implement time sharing. As another example, when the disk has read a block from disk, it generates an interrupt to alert the operating system that the block is ready to be retrieved.
2009年11月2日星期一
看穿双核
一、双核心的由来
所谓双核心处理器,简单地说就是在一块CPU基板上集成两个处理器核心,并通过并行总线将各处理器核心连接起来。双核心并不是一个新概念,而只 是CMP(Chip Multi Processors,单芯片多处理器)中最基本、最简单、最容易实现的一种类型。其实在RISC处理器领域,双核心甚至多核心都早已经实现。CMP最早 是由美国斯坦福大学提出的,其思想是在一块芯片内实现SMP(Symmetrical Multi-Processing,对称多处理)架构,且并行执行不同的进程。早在上个世纪末,惠普和IBM就已经提出双核处理器的可行性设计。IBM 在2001年就推出了基于双核心的Power4处理器,随后是Sun和惠普公司,都先后推出了基于双核架构的UltraSPARC以及PA-RISC芯片,但此时双核心处理器架构还都是在高端的RISC领域,直到前不久Intel和AMD相继推出自己的双核心处理器,双核心才真正走入了主流的X86领域。
MCM模块内封装了4个Power4芯片,共有8个CPU核心
Intel和AMD之所以推出双核心处理器,最重要的原因是原有的普通单核心处理器的频率难于提升,性能没有质的飞跃。由于频率难于提 升,Intel在发布3.8GHz的产品以后只得宣布停止4GHz的产品计划;而AMD在实际频率超过2GHz以后也无法大幅度提升,3GHz成为了 AMD无法逾越的一道坎。正是在这种情况下,为了寻找新的卖点,Intel和AMD都不约而同地祭起了双核心这面大旗。
二、AMD双核心处理器的简介
AMD目前的桌面平台双核心处理器代号为Toledo和Manchester,基本上可以简单看作是把两个Athlon 64所采用的
Venice核心整合在同一个处理器内部,每个核心都拥有独立的512KB或1MB二级缓存,两个核心共享Hyper Transport,从架构上来说相对于目前的Athlon 64架构并没有任何改变。
与Intel的双核心处理器不同的是,由于AMD的Athlon 64处理器内部整和了内存控制器,而且在当初Athlon 64设计时就为双核心做了考虑,但是仍然需要仲裁器来保证其缓存数据的一致性。AMD在此采用了SRQ(System Request Queue,系统请求队列)技术,在工作的时候每一个核心都将其请求放在SRQ中,当获得资源之后请求将会被送往相应的执行核心,所以其缓存数据的一致性 不需要通过北桥芯片,直接在处理器内部就可以完成。与Intel的双核心处理器相比,其优点是缓存数据延迟得以大大降低。
AMD目前的桌面平台双核心处理器是Athlon 64 X2,其型号按照PR值分为3800+至4800+等几种,同样采用0.09微米制程,Socket 939接口,支持1GHz的Hyper Transport,当然也都支持双通道DDR内存技术。
由于AMD双核心处理器的仲裁器是在CPU内部而不是在北桥芯片上,所以在主板芯片组的选择上要比Intel双核心处理器要宽松得多,甚至可以 说与主板芯片组无关。理论上来说,任何Socket 939的主板通过更新BIOS都可以支持Athlon 64 X2。对普通消费者而言,这样可以保护已有的投资,而不必象Intel双核心处理器那样需要同时升级主板
三、Intel双核心构架剖析
AMD的“真伪双核论”虽无法立足,但它点出的英特尔双核处理器可能出现前端总线资源争抢的问题是否真是实情呢?对此,英特尔表示:AMD并不 了解我们的产品和我们将来产品的技术走向,对自己的竞争对手及其产品妄加猜测和评论的行为是不值得赞赏的。AMD曾经指出奔腾至尊版是两个核心共享一个二 级缓存,这就是一个非常明显的错误。事实上,奔腾至尊版和奔腾D都是每个核心配有独享的一级和二级缓存,不同的是英特尔将双核争用前端总线的任务仲裁功能 放在了芯片组的北桥芯片中。
基于Smithfield衍生出的奔腾至尊版和奔腾D
按照“离得越近、走得越快”的集成电路设计原则,把这些功能组件集成在处理器中确实可以提高效率,减少延迟。不过,在台式机还不可能在短期内就 支持4个内核和更多内核的现实情况下,只要有高带宽的前端系统总线,就算把这些任务仲裁组件外置,对于双核处理器的台式机来说带来的延迟和性能损失也是微 乎其微的。
英特尔945和955系列芯片组目前可提供800MHz(用于目前的奔腾D)和1066MHz(用于奔腾至尊版)前端总线,如果是供一个四核处理器使用,那肯定会造成资源争抢,但对于双核来说,这个带宽已经足够了。英特尔认为目前双核系统中的主要瓶颈还是内存、I/O总线和硬盘系统,提升这些模块的速度才能使整个系统的计算平台更加均衡。
基于这种设计思路,英特尔在945和955系列芯片组中加强了对PCI-Express总线的支持,增加了对更高速DDR2内存的支持,对 SATA(串行ATA)的支持速度增加了一倍由1.5Gb/s升级3Gb/s,进一步增加了磁盘阵列RAID 5 和 RAID 10的支持。
单核奔腾4处理器
此外,英特尔奔腾至尊版有一个独门“绝活”,那就是双核心加超线程的架构,这种架构可同时处理四个线程,这让它在多任务多线程的应用中具有明显优势。而且CMP与SMT(同时多线程,英特尔超线程就是一种SMT技术)的结合是业界公认的处理器重要发展趋势,最早推出双核处理器的IBM也是这一趋势的推动者。
奔腾至尊版的双核
英特尔之所以在奔腾至尊版和奔腾D上采用共享前端总线的双核架构,还是出于双核架构自身的紧凑设计和生产进程方面的考虑,这种架构使英特尔能够迅速推出全系列的双核处理器家族,加快双核处理器的产品化,而且它带来的成本优势也大大降低了奔腾至尊版、奔腾D与现有主流单核处理器——奔腾4系列的差价,有利于双核处理器在PC市场上的迅速普及。
四、AMD双核心架构剖析
从架构上来看,Athlon 64 X2除了多个“芯”外与目前的Athlon 64并没有任何区别。Athlon 64 X2的大多数技术特征、功能与目前市售的、基于AMD64架构的处理器是一样的,而且这些双核心处理器仍将使用1GHz HyperTransport总线与芯片组连接及支持双通道DDR内存技术。
实际上Toledo核心就相当于是两个San Diego核心的Athlon 64处理器的集成,至于Manchester自然就相当于两个
Venice核心了—这也就是说,双核心的Athlon 64 X2处理器均将支持SSE3指令集。
另外我们不难发现的是,AMD的台式双核心处理器的频率与其单核心产品基本上处于同一水平上—这一点与Intel非常不一样(Intel目前频率最高的桌面单核心处理器达到了3.8GHz,而其最高频率的双核心处理器只不过3.2GHz)。当然这并不难理解,因为 Athlon 64处理器,特别是采用了90nm SOI工艺的Athlon 64处理器的发热量要比Intel的高频率的Prescott核心处理器要低不少,所以自然可以采用比较高的工作频率了(当然从频率的角度来看,Athlon 64 X2也还是低于Pentium D的)。
由于Intel受发热量限制目前的双核心处理器最高只有3.2GHz,因此在性能上肯定要比AMD的 Athlon 64 X2要低一些——不过Pentium D不如Athlon64 X2的地方并不仅仅只有这方面而已。在处理器的架构上AMD也有其独到之处,下图所示就是AMD的双核心处理器的架构示意图。
AMD的双核心方案面临一个重要的问题,就是随着第二核心的出现,对内存与I/O带宽的资源将会出现争夺,如何解决好这个问题是AMD双核心处理器的性能的关键问题之一。与Pentium D不同的是,Athlon 64 X2的两个内核并不需要通过外部FSB通信这一途径。Athlon 64 X2内部整合了一个System Request Queue(SRQ)仲裁装备,每一个核心将其请求放在SRQ中,当获得资源之后请求将会被送往相应的执行核心,所有的过程都在CPU核心范围之内完成。
AMD双核心强调是真正将两个核心崁入整合在一个硅晶内核上,可以真正发挥双核心效率,不像对手的产品事实上为两个Packet的设计,会有两个核心之间传输瓶颈的问题。因此Athlon 64 X2的架构要优于Pentium D架构,尤其是在高负载的多线程/多任务的环境下,AMD的处理器将会表现出比Intel的处理器更好的性能。
此外,随着第二核心的出现,对内存与I/O带宽的资源将会出现争夺,如何解决好这个问题是AMD双核心处理器的性能的关键问题之一。AMD信引入了Crossbar控制器,这个全新的控制器结合优化的系统请求队列,可以有效的降低这个问题的危害性。
AMD处理器集成的内存控制器在进化到双核心时代表现出来的优势更加明显,低延时的内存控制器使得对CPU的缓存的依赖也大幅减少,在这样的情况下,在日后过渡到多核心的时候,需要考虑的问题更多的是基于各个核心之间的连接。我们可以看到,两个核心所采用的L2缓存也是分别独享的,也就是两个L2缓存中保存的数据是一致的。
实际的可利用容量和一个核心的L2缓存容量是相同的—这一点和Intel一样。与Intel有所不同的是,AMD方案的两个核心之间的通信是通过处理器内部的Crossbar实现的。相比之下Intel的Pentium D处理器的核心之间的通信则是需要通过芯片组的MCH来进行—这显然比AMD的方案要带来更多的延迟时间。不过AMD的架构也并非十全十美,双核心处理器仍然只支持双通道DDR400内存无疑是一个有些令人遗憾的地方—两个处理器核心自然需要更大的内存带宽。要解决这个矛盾,只能使用全新的针脚设计,DDR2或许是一个不错的选择。
Athlon 64 X2这样的设计还有一个好处,那就是如果打算支持新的双内核处理器的话,对旧平台而言唯一的要求就是升级到最新BIOS就OK了,这将大大降低平台的应用、升级成本。当然AMD沿用以前的内存控制器也是有很大的好处的,那就是双核心的Athlon 64 X2处理器可以在目前几乎所有的Socket 939主板上使用。这方面AMD有着Intel无可比拟的优势—因为以前的915/925主板并不能支持Intel的双核心处理器。
此外,与Pentium D是通过降低频率来降低功耗不同,同样采用0.0
9微米生产技术的Athlon 64 X2似乎并不需要面临这样的问题。这都得益于AMD在Athlon 64 X2处理器上所采用的“Dual Stress Liner”应变硅技术。Dual Stress Liner技术是由AMD和IBM联合开发的,据称可以将半导体晶体管的响应速度提高24%。
事实上,DSL很类似于英特尔在90nm生产技术中引入的应变硅技术。我们都知道,晶体管越微细化,运行速度就越高,但同时也会引发泄漏电流增加、开关效率降低,从而导致耗电和发热量的增加。而DSL通过向晶体管的硅层施加应力,同时实现了速度的提高与耗电量的降低。
与Intel使用的应变硅不同,来自AMD和IBM的DSL能够被用于两种类型的晶体管:NMOS和PMOS(具有n和p通道)而无需使用极难获得的硅锗层,硅锗层会增加成本,并且有可能影响芯片的产量。 DSL这种双重性,让它比英特尔的应变硅更有效—DSL可以将晶体管的响应速度提升24%,而应变硅能提供的最大改进在15-20%。
并且更重要的是,AMD和IBM 这项新技术对产量及生产成本并没有任何负面影响。由于在生产时无需使用新的生产方法,所以使用标准生产设备和材料便可迅速展开量产。另外,配合使用硅绝缘膜构造(SOI,绝缘体上硅)与应变硅,还可生产性能更高、耗电更低的晶体管。AMD工程师们表示,DSL和SOI一起结合可以让Athlon 64处理器的频率潜力有大约16%的增长。而Athlon 64 X2的初始频率与目前Athlon 64持平上也可以看到DSL技术的确很有效。
当然,AMD也将在未来转移更先进的65nm生产线上,改进他们的内存控制器来对DDR2,DDR3和FB-DIMM等高性能内存提供支持,也将开始使用更快的HyperTransport 2.0总线,及更有效的节能降耗技术。
五、双核心技术与超线程技术的区别
超线程技术已经不是什么新鲜事物了,但普通用户可能与双核心技术区分不开。例如开启了超线程技术的Pentium 4 530与Pentium D 530在操作系统中都同样被识别为两颗处理器,它们究竟是不是一样的呢?这个问题确实具有迷惑性。
其实,可以简单地把双核心技术理解为两个"物理"处理器,是一种"硬"的方式;而超线程技术只是两个"逻辑"处理器,是一种"软"的方式。
从原理上来说,超线程技术属于Intel版本的多线程技术。这种技术可以让单CPU拥有处理多线程的能力,而物理上只使用一个处理器。超线程技术为每个物理处理器设置了两个入口-AS(Architecture State,架构状态)接口,从而使操作系统等软件将其识别为两个逻辑处理器。这两个逻辑处理器像传统处理器一样,都有独立的IA-32架构,它们可以分别进入暂停、中断状态,或直接执行特殊线程,并且每个逻辑处理器都拥有APIC(Advanced Programmable Interrupt Controller,高级可编程中断控制器)。
虽然支持超线程的Pentium 4能同时执行两个线程,但不同于传统的双处理器平台或双内核处理器,超线程中的两个逻辑处理器并没有独立的执行单元、整数单元、寄存器甚至缓存等等资源。它们在运行过程中仍需要共用执行单元、缓存和系统总线接口。在执行多线程时两个逻辑处理器均是交替工作,如果两个线程都同时需要某一个资源时,其中一个要暂停并要让出资源,要待那些资源闲置时才能继续。因此,超线程技术所带来的性能提升远不能等同于两个相同时钟频率处理器带来的性能提升。可以说Intel 的超线程技术仅可以看做是对单个处理器运算资源的优化利用。
而双核心技术则是通过"硬"的物理核心实现多线程工作:每个核心拥有独立的指令集、执行单元,与超线程中所采用的模拟共享机制完全不一样。在操作系统看来,它是实实在在的双处理器,可以同时执行多项任务,能让处理器资源真正实现并行处理模式,其效率和性能提升要比超线程技术要高得多,不可同日而语。
六、双核心处理器的适用范围
目前,Windows XP专业版等操作系统支持双物理核心和四个逻辑核心,但这并不意味着所有软件对此都有优化。
事实上大量的测试已经证明,无论是Intel还是AMD的双核心处理器,相对于其各自的同频率的单核心处理器而言,对于目前的普通应用例如多媒体软件、游戏和办公软件等等都没有任何性能提升,甚至可能还稍有降低,因为这些普通应用目前都还只是单线程程序,在处理器执行指令时实际上只有一个核心在工作,而另外一个核心则处于空闲状态帮不上忙。
所以对普通用户而言,只要日常应用的程序仍然是单线程的话,双核心处理器实际上没有任何意义,反而还增大了购买成本。除非经常执行大运算量的多任务处理,例如在游戏的同时进行音视
频处理等等,这时双核心处理器才能真正发挥作用。
目前最适合双核心处理器发挥威力的平台是服务器和工作站,这是因为其经常进行多任务处理,而且日常运行的大量程序都是多线程程序,例如图形工作站所使用的Adobe Photoshop和3D MAX等都是多线程程序。一般来说,在执行多任务处理和多线程程序时,双核心处理器要比同频率的单核心处理器的性能要高大约50%-70%,甚至在某些应用下性能几乎能提升100%。
当然,随着双核心处理器的强势推出和逐渐普及,日后支持多线程的普通应用程序也会逐渐增多,对普通用户而言那时双核心处理器才会真正发挥作用。
七、双核心处理器目前所存在的问题
无论是Intel的Pentium D和Pentium EE,还是AMD的Athlon 64 X2处理器,都是简单地将两个物理内核"叠加"在一起,这必然带来晶体管数量的大幅度增加,双方都已经达到了两亿三千万个以上的晶体管;带来的直接后果就是由泄漏电流引起的功耗大幅度增加,就算是采用了节能技术其发热量也居高不下,从而导致双核心处理器相对于单核心处理器而言频率提升更加困难。
而且由于目前的制造工艺的限制,双核心处理器的良品率要比单核心处理器的低,这必然会带来成本的居高不下,所以目前的双核心处理器的价格都太贵了,距离普及还差得很远。当然,随着处理器核心架构和制造技术的发展,今后必然会解决目前所遇到的问题。
2009年9月18日星期五
Virtualbox下我很愚蠢的错误
命令:net use x:\\vboxsrv\Download
发生系统错误 67
找不到网络名
我看了n遍帮助一直觉得没错。差点没疯了。
终于今天看到发现了天机了,
寒,少了个空格。
应该是:net use x: \\vboxsrv\Download
应该还是我自己没理解这句命令的含义,嗨~
2009年9月17日星期四
抢占式内核
本文译者:
康华:计算机硕士,主要从事Linux操作系统内核、Linux技术标准、计算机安全、软件测试等领域的研究与开发工作,现就职于信息产业部软件与集成电路促进中心所属的MII-HP Linux软件实验室。如果需要可以联系通过kanghua151@msn.com联系他。
注明:棕色写的内容为译者注。
如果有意义不明之处请参见原文。
Kevin 将继续他的实时之旅,这次他要着重分析如何通过改造Linux内核来为应用程序带来实时性能。
在2002年的1-2月发行的嵌入Linux月刊中,我们探讨了有关实时和Linux的基础问题。而这次我将精力花在改造Linux内核来为应用程序带来实时性能这个主题上。到目前为止,工作的重心集中在提高内核响应速度——通过减少抢占响应时间缩短系统响应时间,因为我们知道抢占响应时间在Linux中耗时较长。
通过改进内核——仅仅是剔除一些标准内核的功能——并不去改变或增加内核API,应用程序就可以获得更快的响应速度。这样做优势明显,因为ISVs(独立软件开发商)不需要为不同的实时要求开发不同版本的系统。比如,DVD播放器可以在一个改进过的内核上更稳定的运行,而它不必知道该内核是经过改进的版本。
背景和历史
自2.2版本内核发布以来,内核抢占成为一个热门话题。Paul Barton-Davis 和 Benno Senoner曾给Linus
Torvalds写了一封信(该信后来追加了许多人的签名),请求在2.4版本内核中显著降低抢占延迟时间。
他们需要Linux性能上能满足播放音频、音乐以及MIDI的要求。Senoner开发了一套基准软件(benchmarking
software)测试2.2版本内核(以及后来的2.4版本),在最坏情况下发现抢占延迟高达100毫秒(参考)。 对于音频应用程序来说,这么长的延迟时间显然是无法接受的。因为经验显示系统响应时间只有在几毫秒内才能满足音频应用程序的需要。
有两个补丁包为内核提供了相当不错的抢占响应速度提升。Ingo Molnar (来自 Red Hat) 和 Andrew Morton (来自Wollongong大学)
两人都开发了内核补丁,这些补丁为内核中长代码路径片段插入了抢占点。你可以在这里这里发现Ingo Molnar的补丁包 ,或在这里找到Andrew Morton的补丁包。
另外,Morton还提供了测量响应速度的工具,比如测量内核忽视请求时间长度等,有关详细信息在他的快速响应补丁网站上可以找到。
目前,至少有两个组织开发了抢占式内核,为内核抢占问题提供了更基础、更强大的解决途径。
在2002年1-2月ELJ上发表的系列文章的第一篇中,我列举了不少希望Linux能够支持的实时功能,它们包括多优先级、用户空间中断处理和DMA、同步机制中的优先级继承(优先级继承可用来解决优先级反转问题。当优先级反转发生时,优先级较低的任务被暂时地提高它的优先级,使得该任务能尽快执行,释放出优先级较高的任务所需要的资源)、微妙级的时钟解析度 、全面实现POSIX1003.1b规范要求的功能和调度程序的恒量耗时算法等。我们在本文中也会简要讨论它们。
要
明白这些性能改进都必须依赖给内核打补丁,但是打补丁后的内核就不再兼容其它标准内核了,比如抢占式内核需要修改自旋锁的代码,这时如果一个驱动程序的二
进制执行文件如果不采用修改过的自旋锁,那么很可能无法正常抢占。所以改造内核时一般都需要内核源代码并重新编译内核代码。值得一提的是,使用模块化的Linux驱动程序是使得源代码兼容的一个有效方法。我们不赞成仅仅发布驱动程序的已经编译的二进制文件而没有源代码,因为这样作既缺乏兼容性保障也不符合开源精神。
改进
各种各样对内核的改进能够为应用程序透明地提供众多好处。比如,提高内核的抢占性主要通过抢占式内核或是添加抢占点着两个途径。从内核角度进行改进可以使得应用程序不用做修改就能获得高的响应速度。
透明性也应该考虑是否改变对内核来说也是透明的,换句话说就是,是否采用的方法能自动跟踪内核的改变。Molnar和Morton提出的插入抢占点的方法需要测量新内核中的调度响应时间,并且在此基础上插入抢占点到合适位置。
相反,如果在SMP锁定基础上创建抢占式内核,则可以自动、无须修改地过渡到新内核。而且如果在SMP-锁定机制中实现抢占性,则当内核开发者提高SMP锁定粒度(granularity)时,也同时会自动提高抢占粒度。我们会看到SMP锁定将粒度稳步提高,因为SMP不断扩张必定需要不断提高锁定粒度。
正是由于这种新引进的SMP锁,内核抢占才自2.4版本或更新(实际在2.6才正是支持)内核后被正式实现。而早期内核缺乏SMP锁。
抢占式内核的另外一个需要强调的重要优势是它使得代码——但代码不会发觉——可被抢占,比如,驱动程序开发者不必为要使驱动程序可被抢占去编写任何特殊代码,驱动程序的代码能在必要时被抢占,除非驱动程序持有锁。所以在内核其它部分,编写优良的SMP安全(代码中不存在多处理器并发访问共享资源的危险)的驱动程序将自动受益于抢占式内核。而另一方面,非SMP安全的驱动程序可能不能和抢占式内核和谐工作。
也许有人会发觉,只要某些驱动程序没有请求锁,内核代码就可以调用它。比如我们使用MontaVista的抢占式内核做简单测试中发现,动态装载的驱动程序中read()和write()函数都可以正常被抢占,但是函数init_module()、open()和close()却不能。这意味着如果一个低优先级的进程执行操作open()或close(),那么它有可能被一个新唤醒的高优先级别进程推迟抢占时机。
实际上,开发者最好去测量响应时间,因为即使使用抢占式内核,我们也有可能找到有那些代码片段持有锁的时间超过了应用程序允许的长间。
比如MontaVista, 提供了一个抢占式内核,对那些长期持锁的代码片段插入了抢占点,同时也提供了测量工具,以便开发者可以测量它们实际应用程序和环境的抢占性。
SMP锁的目的是确保内核重入(re-entrance)安全。也就是,如果并行运行的进程需要访问内核资源,那么对这些资源访问必须安全、可靠。越精细的锁定粒度越能保证竞争进程运行的并行巡行能力越强。因为并行能力的提高需要减少堵塞(因为锁的争用),(而细粒度锁可减少阻塞机会)。
上述概念也同样适用于单处理器。对于I/O系统来说,如果将I/O设备看作一个独立的处理器,那么应用程序和I/O活动的并行运行无疑能提高系统吞吐量。提高抢占性,意味着高优先级的I/O范畴进程(I/O-bound process)会更频繁地被唤醒,从而提高了吞吐量。这样以来,虽然可能带来某些负作用,比如我们可能会需要更多的上下文切换和在内核关键路径上执行更多代码(关键路径直那些访问共享资源的代码路径,为了防止竞争条件需要上锁等操作),但是即使如此,我们仍然可以获得更大的系统吞吐量。
允许内核抢占的优势是显而易见的,标准内核迟早会引入抢占功能(目前已经具有)。抢占式内核有些实现中可以提供几微妙的响应时间,而更精确的实现则可把响应时间提高到几十分之一微秒。
环顾嵌入Linux生产商,MontaVista 和TimeSys提供了抢占式内核;REDSonic使用抢占点;LynuxWorks和红帽子使用RTLinux;Lineo
使用RTAI;OnCore通过和Linux系统调用兼容的API(和LynuxWorks利用LynuxOs一样)与在他们的抢占式微内核上。
运行一个Linux内核(可抢占的)达到实时目的。
抢占点
抢占点的核心思想是在特定点上调用调度程序去检查是否有更高优级的任务做好了运行准备,需要即刻运行。Molnar和Morton就是利用该思想,测量内核路径的执行时间,找到时间过长的路径插入调度检查点(等于打断了长路径)。你可以通过抢占补丁代码或是对比打过补丁的内核和先前未达补丁的内核,从中发现那些地方需要插入抢占点。抢占补丁看起来很象if (current ->need_resched) schedule()(这是用户空间抢占执行的典型情形);
为了使用Andrew Morton开发的抢占点内核补丁,需要从上面给出的URL下载该补丁,同时还要从kernel.org下载恰当版本的内核源代码。然后内核打上补丁然后重新编译,详细细节可以在这里找到,但要注意这些是为2.4版本老版本内核而言的。另外还请注意你可能需要升级你的开发环境。
使用Molnar的补丁要做的事情同上。下载补丁、编译新内核,Morton开发了针对2.4多个版本的补丁。而Molnar的补丁针对一些2.2版本内核和早期的2.4版本内核。
抢占式内核
抢占式内核使得用户程序在执行系统调用期间可以被抢占,从而使新被唤醒的高优先级进程能够运行。这种抢占并非可以在内核中任意位置都能安全进行,比如在临界区中的代码就不能发生抢占。临界区是指同一时间内不可以有超过一个进程在其中执行的指令序列。在Linux内核中这些部分需要用自旋锁保护。
MontaVista
和 TimeSys采用类似的方法建立抢占式内核。他们巧妙地将自旋锁的功能加强为也能防止抢占(2.6新内核中自选锁也是这样做的)。依靠该方法,抢占只能发生在未使用自旋锁的其它部分。当一个更高优先级的进程被唤醒,调度程序就能抢占低优先级进程正在执行的系统调用,只要此刻该系统调用代码没有被自旋锁保护——加上自旋锁意味不可抢占。
另外,使用抢占式内核,打断锁(解开再锁上)使得重新调度相比采用抢占点(低响应时间)补丁要简单。因为如果内核释放了一个锁,然后又再获得它,那么当锁被释放时,就会进行抢占检查。内核中有些地方需要上锁——比如一个循环——但不需要一直持有锁,可以每进行一次循环,锁就要被释放,然后再获得。
MontaVista实现抢占主要通过一个计数器(2.6版本中称它为抢占计数,用它可以跟踪锁定嵌套数),当自旋锁被获取时,该计数就增加1。当高优先级别的进程被唤醒,调度程序会检查抢占计数——检查是否为零——判断是否此刻允许抢占(如果为0,就可以发生抢占)。依靠这个计数器,当锁嵌套调用时,抢占机制能很好的工作,但是任何持有自旋锁的临界区域都不允许抢占,即使锁用来保护的是些无关资源。
TimeSys采用一个优先级遗传互斥量(priority inheritance mutex)。利用这种机制,一个高优先级的进程可以抢占一个持有不同资源互斥量的低优先级别的进程。另外因为采用了优先级遗传,所以持有互斥量的低优先级的进程不能无限推迟等待在该互斥量上的高优先级进程。这样以来解决了所谓的优先级翻转问题(Priority Inversion Problem)。
MontaVista公司开发的抢占包可以从SourceForge kpreempt 站点获得。MontaVista公司的开源精神很值得赞赏,他们同时也提供了他们的实时调度程序与高解析度定时器,这些都可以从SourceForge的这里和这里获得。
SourceForge
的kpreempt 项目同时也含有Robert Love开发的抢占式内核的连接(请看2002年4月和5月出版的Linux杂志,其中介绍了他对内核改进的详细信息)。 另外 MontaVista的补丁也由Love维护(现在Robert Love已经归于MontaVista麾下),虽然MontaVista 也参与维护工作。最新的补丁可在此处下载。
Love最新发布的补丁现在已经可以和Ingo Molnar的恒时(耗时为衡量)调度程序补丁协同工作。Molnar的时间复杂度为O(1)的调度程序可以用于2.4版本内核,并且目前也已经植入了2.5版本的内核中了。TimeSys也将自己的抢占式内核发布在了他们的网站上。抢占式内核需要的补丁包都已经完备。要得到这些补丁,你需要将它们对比2.4.7内核代码数生成diff文件。上述的这些抢占式内核程序都遵守GPL协议。
TimeSys还为实时程序开发者提供了许多额外功能,这些功能不能无偿下载。它们包括实时调度和实时资源分配技术。这些模块填加了额外的系统调用,比如提供对新增功能的访问方法等。
如果那些朋友对这些细节感性趣,可以通过我们提供的许多线索找到想要的信息。自旋锁机制的关键信息包含在文件include/linux/spinlock.h中,MontaVista
和TimeSys都对该文件进行了修改。
有趣的是,虽然MontaVista 和TimeSys都对旧函数改了名字,但是他们仍然使用这些旧函数。以前老的自旋锁函数仍然需要。比如不允许在调度程序执行期间发生抢占内核的行为,否则会带来无穷无尽的递归调用。MontaVista使用象_raw_spin_lock和
_raw_read_lock这样的命名;TimeSys 使用象old_spin_lock 和
old_spin_lock_irq这样的命名。
可以在TimeSys发布的代码kernel/include/linux/mutex.h中发现它是利用write_lock() 和 read_lock()函数——他们实现了互斥锁——定义自旋锁的。具体实现函数do_write_lock()可以在文件kernel/kernel/mutex.c中看到,它实现了互斥锁定功能。
其它的内核实时方法
另一个能有效提高实时性的方法是提高时钟的粒度。TimeSys, MontaVista, REDSonic 和其他公司都提高了时钟解析度,比如,TimeSys 在上下文切换期间使用Pentium处理器的时间戳计数器(Stamp Counter)来确保准确地对CPU时间进行记帐,该记帐值要被诸如 getrusage()等函数用到。
许多开发者,也包含作者都认为Linux缺乏对POSIX1003的全面支持是个很重要的缺陷。幸运的是,目前已经有了解决方法,特别是,TimeSys公司已经有了一个不错的实现。
除了对POSIX的贡献外,TimeSys已经开发了一些全新的资源访问控制机制。这些新技术使得实时应用程序可以节约CPU时间或网络带宽。比如结合它们的中断线程模型、抢占式内核和其它功能,能提供高出标准内核2或3倍的响应速度。
到目前为止,Linux好象还不允许让用户空间应用程序自己注册函数处理中断,该机制称为用户空间中断处理机制,它目前已经在RIX、SGI's UNIX等系统中得到使用。
有趣的是,SGI在Linux中,利用他们的ds1286实时时钟接口,可以从用户空间通过一个实时时钟访问中断。可以在这里.找到相关信息
和用户级别中断处理相关的是用户空间和设备的DMA通讯,提供此功能的补丁可以从这里获得。
保证
显然,没有哪个实时Linux厂商愿意保证响应速度。如果提供保证的话,那么应该类似下面的声明:
使用我们的Linux内核,和所需的硬件与设备等,我们可以保证你的应用程序如果被锁在内存,具有最高优先权。。那么将能够在你实时硬件发出中断信号后的N微妙内被唤醒。如果你无法获得上述能力,我们将视其为一个bug。
但是我们从没看到过该类保证,这是为什么呢? 我们认为有如下几种可能。
厂商的这种保证毫无意义,没有客户需要它。但我们认为许多开发者希望获得保证,事实上,硬实时本身就意味着一个保证。
厂
商没有充分测量他们的内核和环境,以至于有能力给出一个保证。这是一个小花招。因为单独测量无法给出另人满意的保证,代码必须在所有环境中被测试而且要在
最坏情况下测试。从厂商的宣称中,看起来它们似乎已经花了大量精力去测量和学习代码,但事实上,对工程师来说可能给出给定环境下的一些数据更能让人放心。
如果考虑所有需要保证的方面,Linux所涉及的方面实在是太多了。这点可能就是问题的所在。开发者希望能够改写他们的内核,他们希望能下载驱动程序并使用。这些行为都超出了厂商的控制,所以如果厂商公开声明一个保证,就有可能仅仅是针对某一个特定系统在一些选定的情况下才有效的。
也许我们会看到某些妥协的保证,例如像“在Pentium
系列的计算机上应用程序响应速度为100ms或更短”另外加上驱动程序花去的时间。驱动程序使用的时间非常重要,因为驱动程序中的中断处理代码往往在响应时间中占主要部分。
