概述
QNX的体系架构概述
Dan Hildebrand
Quantum Software Systems Ltd. 量子软件系统有限公司
175 Terrence Matthews
Kanata, Ontario K2M 1W8
Canada
(613) 591-0931
danh@quantum.on.ca
摘要
本文从架构视角上来展现QNX操作系统。QNX操作系统为应用程序提供了完整的面向网络、多处理器和分布式的实时环境,几乎可以实现底层硬件在驱动级别上的全部性能特性。用于交付这个操作环境的OS体系结构,是由一系列可选进程围绕着实时微内核,这些进程提供了POSIX和UNIX兼容的系统服务。通过对运行时中包含或排除各种资源管理器,可以将QNX缩减为基于ROM的嵌入式系统,或者扩展到包含数百个处理器——通过各种LAN技术紧密或松散地连接在一起。与POSIX标准1003.1、草案标准1003.2(Shell脚本和实用工具)和草案标准1003.4(实时)的兼容性会在整个分布式环境中被透明地维护。
*本论文发表于西雅图1992年4月,关于微内核和其它内核架构的USENIX研讨会。ISBN 1-880446-42-1。QNX是注册商标,FLEET是量子软件系统有限公司的商标。
架构:历史和现状
自从它在1982年被创建以来,QNX体系结构从根本上一直类似于它当前的形式——一个非常小的微内核(当时大约为10KB),由一组协作的进程所围绕着,来提供更高级别的操作系统服务。到目前为止,QNX已经在近20万个系统中使用,主要应用于要求实时性能、开发灵活性和网络灵活性的应用程序中。大量的安装已经证明,微内核技术在商业上是可行的,并适合于关键任务应用,例如过程控制、医疗仪器和金融交易处理等。这些应用程序的性能需求一直是QNX从1.00版本到3.15版本演进的重要驱动力。
在1989年开始开发的兼容POSIX的QNX (4.0)版本,以最大化继承前一代产品的性能和灵活性为目标。这个新版本发布于1991年。本文将详细介绍新架构的特点,并讨论其优势和限制,以及未来发展的目标。
真正的微内核
QNX微内核实现了四个服务:进程间通信、低级网络通信、进程调度和中断调度。有14个与这些服务相关的内核调用。总体而言,这些功能占据大约7KB的代码,并提供实时执行的功能和性能(参见附录A)。考虑到内核的大小很小,一个提供了合理的片上缓存的处理器,就可以为大量使用微内核服务的应用程序提供优良的性能,因为微内核和系统中断处理程序通常可以适应CPU的8KB片上缓存。
图1: QNX微内核
微内核以阻塞版本的Send()、Receive()和Reply()来提供的消息传递功能。也即是说,一个进程使用Send()发送到另一个进程时将被阻塞,直到目标进程执行Receive()、处理消息并执行Reply()。如果一个进程执行Receive()后没有消息被传递,它将被阻塞直到另一个进程执行Send()。由于这些原语不经过队列,而直接从进程复制到进程,其消息传递的性能接近底层硬件的内存带宽。所有的系统服务都建立在这些消息传递原语之上。使用这些低级服务,可以很容易被实现这些IPC原语的变体(例如消息队列)的服务。
相对于单内核(Monolithic-kernel)中实现的这些服务的性能,这些替代的IPC服务的性能与之相当,而且常常更加优越 (见附录B)。
图2:典型的发送-接收-回传事务中的涉及的状态
进程可以请求以优先级顺序(而不是按时间先后顺序)来处理消息,并且以因等待服务而阻塞的进程中的最高优先级来执行。这种消息驱动的优先级机制,巧妙地避免了在固定优先级消息传递系统中,可能导致的优先级反转问题。服务进程被强制以它们所服务的进程的优先级来执行,并且当高优先级进程阻塞在繁忙的服务上时,服务进程的优先级还会自动的得到适当的提升。因此,低优先级的进程不能通过调用一个更高优先级的服务进程上的服务来抢占更高优先级的进程。
消息传递原语支持多部件(multi-part)的消息传递,这样从一个进程传递到另一个进程的消息不需要占用内存中的单个连续区域。与之相反,发送和接收进程都可以指定一个MX表(MX table),它指示了在内存中发送和接收消息片段的位置。这使得消息头块与数据块可以分隔开,而不需要为了创建一个连续的消息,而执行消耗性能的数据复制。此外,如果底层数据结构是一个环形缓冲区,那么一种三部件(three-part)的消息将允许在环形缓冲区内的头和两个不相交的区间作为单一的原子消息来发送。发送方和接收方各自应用到消息的MX映射(MX mapping)不必是相同的。
图3:多部件消息可以通过使用MX控制结构来指定。微内核会将这些数据组装到单一数据流中。
低级网络通信被直接设计到了微内核中,并由被称为网络管理器的可选进程来提供(本文稍后将介绍)。当存在网络管理器时,它会直接连接到微内核,并为微内核提供将消息复制到LAN上的其它微内核所需的功能。通过在系统中基础层面上提供的网络服务,任何在操作系统中的更高架构层上提供的服务,都可以透明地被任何进程、在网络上的任何地方访问。从架构上讲,这个实现非常精简,尽可能的提供了高效的接口。
QNX提供的进程调度原语符合POSIX 1003.4(实时)草案规范。QNX提供了完全抢占式、轮询的优先级的上下文切换、FIFO和自适应调度。当POSIX 1003.4标准走出草案状态时,微内核和系统进程将被演化以进行匹配。
资源管理器和路径名空间管理
对于要提供POSIX标准和UNIX约定指定的功能的微内核,可以添加被称为资源管理器的可选进程。一个没有文件系统或设备I/O系统的最小系统,可以构建为微内核、进程管理器和一组应用程序进程。
第一个,也是唯一一个强制性的资源管理器是进程管理器(Proc)。Proc提供了诸如进程创建、进程会计(process accounting)、内存管理、进程环境继承(包括本地和网络远程进程)和路径名空间管理的服务。第一级路径名管理是由Proc完成的,因为不同于单内核系统中始终存在文件系统,在QNX下文件系统是可选的。无磁盘或基于ROM的系统可能不需要文件系统,因此也不必强制使用。
在资源管理器开始执行之前,Proc“拥有”整个路径名空间(根和根下面的一切)。如果没有任何资源管理器提供服务,这本质上就是一个空文件系统。Proc允许资源管理器通过一个标准的API来使用名称空间中,它们想要管理的部分(一个“授权领域”)。然后,Proc负责维护一个前缀树来跟踪拥有路径名空间各个部分的进程。
当Fsys(文件系统管理器)和Dev(设备管理器)正在运行时,前缀树将如下所示:
/ 基于磁盘的文件系统 (Fsys)
/dev 字符设备系统 (Dev)
/dev/hd0 原始磁盘卷 (Fsys)
/dev/null 空设备 (Dev)
当一个进程打开一个文件时,open()库例程首先将文件名发送到Proc,在这里将路径名应用于前缀树,以便将open()指向适当的资源管理器。在授权领域重叠的情况下,对路径名的最长匹配将获胜。例如,如果 /dev/tty0 被打开,最长的匹配将发生在 /dev 上,使得open指向 /dev。路径名 /usr/fred 将匹配到 / ,使得打开到Fsys。
网络中的每台计算机上的进程管理器,都会维护它自己的前缀树,并可能对在每个节点上的进程,呈现出相同或不同的视图的网络范围路径名空间。以 / 开头的路径名会应用到该节点上的前缀树。应用程序也可以使用网络惟一名称,用来指定网络范围路径名空间中资源的绝对位置。通过使用前缀别名,可以将名称空间的一部分映射到其他网络节点的资源管理器上。例如,从LAN启动的无盘工作站,想要将其文件系统挂载在另一个节点上,从而可以将其文件系统的根别名到远程的Fsys进程。
有了这个别名,对 /dev 的open()调用将仍被映射到本地的Dev进程以控制本地的设备,但所有对文件的open()调用则会导致打开消息在先前指定的远程节点上的前缀映射表上进行解析(通常将对文件的打开操作,引导到那个结点上的Fsys进程)。因此,网络上任何地方的进程都可以在单个目录树上访问所有的网络文件系统资源,连接到一个公共根目录。或者,通过使用网络绝对路径名,网络路径名空间也可以被操作为单个根文件系统的集合。
通过在常规的文件命名空间中实现各个域的权限,使得整个操作系统的各个功能部分,可以以运行时可选(runtime-optional)的方式实现。由于资源管理器位于内核空间之外,并且与用户进程没有本质区别,因此可以在运行时动态地添加或删除它们,而不需要将内核重新链接以便包含不同级别的功能。根据应用程序的需要,这种分级的灵活性使得操作系统可以轻松地的放大或缩小。
尽管将资源管理器提供的服务放置在内核之外,但最初看起来效率很低,但是在附录B中给出的性能结果表明,微内核的上下文切换和IPC性能足以匹配硬件的原始性能。
这个名称空间的网络透明性允许远程执行进程,在逻辑上等同于在本地处理器上的执行。单独管理的路径名空间无缝地融合,并且在名称空间的行为方式上没有“惊喜”。在继承了整个的父进程环境,包括打开的文件描述符、环境变量和当前的工作目录之后,尽管处于网络分布式运行时的上下文,处理器间通信和文件I/O都是按照POSIX 1003.1规范操作的。
Fsys——文件系统管理器
Fsys是资源管理器,它为QNX环境提供了一个符合POSIX的文件系统。它实现了一个磁盘结构,该结构使用了位图来分配空闲空间,并使用了一种扩充的链表的方法来组织磁盘上的数据。这种方法允许系统在应用程序级上达到接近硬件原始性能的磁盘吞吐量(见附录B)。Fsys将对文件系统的完整性至关重要的数据结构同步写入磁盘,从而使得磁盘系统在意外断电的情况后还能够顺利地运行。在磁盘数据结构中嵌入的特殊标记,使得文件系统在发生灾难性故障时很容易被重建。
Fsys的多线程体系结构允许它并行处理多个请求,这样当其他线程被阻塞时,就会触发虚拟硬盘(Ramdisk)和缓存I/O,等待发生物理I/O。这种并行性也延伸到了驱动程序中——如果一个设备支持多个待处理的I/O请求,那么驱动程序可以以任何合适的顺序为这些请求来服务。
尽管对消息传递类操作系统的初步研究表明,这个文件系统可能需要比单内核文件系统复制更多的数据,但实际情况是不需要额外的复制。MX多部件消息原语允许Fsys将应用程序调用read()和write()时指定的连续缓冲区,映射到Fsys中非连续缓存块。对于读取磁盘,磁盘驱动器从磁盘读取到多个非连续的由LRU算法分配的缓存块。然后,Fsys在内核中调用MX工具以原子方式收集并将分散的块,复制到应用程序指定的连续读取缓冲区中。因此,即使文件系统存在于一个消息传递类网络透明的环境中,它也显示了与在单内核中实现的文件系统相同数量的数据复制。
Fsys进程可以从无磁盘连接网络的机器上以命令行方式启动,然后将设备驱动程序动态地附加到Fsys上。如果不再需要Fsys时,可以从内存中删除Fsys及其驱动程序。
Dev——设备管理器
设备管理器 (Dev) 提供了与POSIX兼容的设备控制,并提供了一些适合于实时通信的扩展。类似于Fsys,Dev也可以被动态启动,并附加上其设备驱动程序,然后在不再需要时从内存中删除。
由于微内核提供了较低的中断延迟,开发人员可以在一般的硬件上使用非智能UART设备来处理最高至115 K的波特率。通过添加智能通信板,可以配置高带宽、多线通信服务器。
MX消息传递原语的使用,允许Dev以Receive()收到应用程序对设备执行的write()操作,并将其直接写入由中断处理程序所管理的环形缓冲区中。通过适当地定义MX表,可以将接收到的数据直接写入由Dev管理的循环缓冲区。由于写入一个循环缓冲区可能要求数据被映射到物理上分离(但逻辑上连续)的内存区域,一个有三个条目的MX表可以描述环形缓冲区的头和其上两个物理上不相交的部分。对于read()的情况,来自设备的数据流直接从驱动程序进入环形缓冲区,并从环形缓冲区进入应用程序的read()缓冲区,而不需要进行冗余的复制来构建连续的消息。
设备驱动支持
与其坚持设备驱动程序的中断处理程序只能存在于内核空间中,QNX提供了一个系统调用,允许用户进程将具有足够特权用户进程中的处理程序,连接到内核中的特定中断向量。然后内核可以调用所连接的处理程序来响应物理中断。处理程序通过存在于用户进程中,可以完全访问进程的地址空间以便于响应中断。一旦处理程序开始运行,它可以唤醒与其共享代码的进程,也可以简单地返回内核。Dev的设备驱动程序利用这种行为,使用单独的中断在Dev管理的缓冲区中累积字符,只有在预先定义的“重要事件”(如终端字符计数、行结束条件或超时)发生时才唤醒Dev。
以这种方式在内核外部存在的中断处理程序的情况下,用户可以从正在运行的系统中,动态地添加和删除中断处理程序(以及包含它们的设备驱动程序)。由内核完成的第一级中断处理,还处理嵌套和共享的中断,而不会将依赖硬件的细节和复杂性,强加给用户编写的中断处理程序。微内核对外部中断处理程序的支持,对于资源管理器匹敌单内核内的资源管理所能提供的性能水平是至关重要的。
容易扩展
设备驱动程序存在于用户进程中的一个基本优势是,开发一个操作系统的扩展,在功能上与开发用户级进程没有区别。事实上,在量子公司内部使用的开发方法中,对实验性质的资源管理器的执行,是在全屏的、源代码级调试器的控制下的,从而能够完成对操作系统的服务如一个新的 Fsys 进程的调试,而不必诉诸低功能的工具,如内核调试器通常用于在单内核操作系统中调试内核链接的(kernel-linked)扩展。由于可以随意启动和删除资源管理器和设备驱动程序,重新链接内核并重新引导,以测试新内核的繁琐过程变得完全没有必要。
作为说明QNX系统多么容易扩展的例子,一个在[Pike 90]中描述的与 /proc 资源管理器类似的服务,由应用程序级的程序员(不是内核架构师!),经过仅仅几个小时的努力,以不到200行容易理解的C源代码实现了。实际上,/proc资源管理器打包了一种系统资源(系统中活动进程的列表),然后将其以文件和目录的形式提供给系统,可以在 /proc 路径名空间中进行操作。
作为一个更复杂的示例,一个类似于[Presotto 91]所描述的客户端网络文件系统缓存管理器的实现大约花费了一周的时间。该缓存将最近访问的文件块的副本保存在客户端,供访问网络远程Fsys的节点使用。在open()调用时,缓存管理器会验证远程文件没有被更改(这会使本地缓存的数据无效),并提供本地缓存的数据以提供性能增强。通过为这个客户端缓存提供一个本地磁盘文件以“流入(spill)”到其中,一个通过缓慢的串行链路进行网络连接的系统,仍然可以提供合理的网络远程文件系统性能。该服务器的实现仅1000行源代码,再次的,使用标准系统库的应用程序级程序员完全可以理解它。
最后,可以将客户文件系统实现为一个资源管理器,它使用 Fsys 的原始磁盘块I/O服务在根文件系统中以子树的形式显示客户文件系统。一个例子是 Dosfsys,一个PC-DOS文件系统。Dosfsys采用 /dos 路径名作为其授权域,然后向系统呈现 /dos/a、/dos/b等一系列目录。这些目录映射到了相应的PC-DOS介质,Dosfsys进程会操作这些卷上,输入到Dosfsys的I/O请求所指示的原始块。能够映射到底层文件系统的文件操作是被支持的,而其他操作(如link()),在尝试时则返回适当的错误状态。
网络服务——FLEETTM网络技术
Fault-tolerant 容错性
Load-balancing 负载均衡
Efficient 效率高
Extensible 可扩展
Transparent 透明性
如前所述,网络管理器(Net)是直接连接到微内核中。当微内核被调用来将一个消息从本地进程传递到另一个节点上的进程时,它会通过这个私有接口将指向这个消息的指针排队到Net中。类似地,Net可以接收来自其它微内核的消息,并将这些消息发送给本地微内核。本质上,网络上的网络管理器将许多远程的微内核整合到一个微内核中。由于所有系统服务(包括进程创建、调试、文件和设备I/O)都是通过微内核传递的消息来完成的,所以结果是一个计算机网络的行为类似于一台计算机。在操作系统的更高架构层级上提供的任何服务都可以被网络上的所有进程透明地访问。这与TCP/IP服务套件形成了鲜明的对比,后者只提供非常明确的服务集——通常是终端会话和文件访问。相比之下,这种连接的微内核架构允许以下命令:
ls /usr/danh | grep abc | wc
使每个进程在网络上的不同处理器上运行,而Proc提供网络继承的文件描述符使得管道可以通过网络连接和转发数据。这种环境的透明性也促进了分布式应用程序的实现。例如,从传统的非分布式版make开始,一个网络分布式团队版make实用程序的开发仅用了一周的时间就完成了。
就像Fsys和Dev可以从命令行启动和停止一样,这两个驱动程序都有一组驱动程序族,Net也有一组驱动程序族,支持多个网络驱动程序到Net的连接。如果Net发现不止一个网络驱动程序提供到相同节点的连接,它将在驱动程序之间负载平衡流量。负载均衡使用基于媒体传输速率和队列深度的算法。也可以根据提供的命令行选项,手动控制网络流量。
通过在网络节点之间添加额外的网络链接,节点之间使用多个网络路径可以提供更好的吞吐量和容错能力。不需要在应用程序级进行更改就能利用这种容错性,因为这种支持是在网络管理器内部本地存在的。
图4:多个物理网络通过逻辑网络愉快地共存
如果主LAN发生故障,廉价的串行链路可以用作备用(fall-back)网络链路。通过以高波特率(Dev可以达到115 K波特率)运行串行链路、进行数据压缩和启用客户端文件系统缓存,串行网络的性能也可以非常快。
此功能还可用于解决LAN拥塞问题,也即两个文件服务器在LAN上做大量点到点传输。使用FLEET方法,可以添加一个私有网络链接来连接这两个服务器,从而将点对点流量从主LAN转移到私有链接上。如果两台服务器在物理上是相邻的,那么非传统的LAN技术(如点到点SCSI或总线到总线DMA)就成为可行的选择。此方法可用于实现[Presotto 91]中描述的CPU/文件服务器组。
FLEET方法还允许使用系统底板总线构建多处理器系统,方法是构建一个处理器板,该处理器板将底板总线用作VLAN(Very Local Area Network非常局域网)。每个处理器板将运行一个由微内核、Proc、Net和Net.vlan驱动程序组成的QNX OS。其中一个处理器运行的Net,同时包含Net.vlan驱动程序和Net.ethernet驱动程序,来访问外部以太网LAN。通过向这些处理器添加额外的硬件,以及适当的Dev或Fsys进程,它们就变成了分布式I/O处理器。目前,使用VLAN的微通道总线(Microchannel bus)对该体系结构的测试实现正在与Aox公司共同开发中。微通道突发模式和多主(multimaster)总线仲裁与VLAN一样具有良好的性能。实际上,以太网上的每个节点都可以通过额外的处理器在机箱中包含VLAN。这使得通常在每个以太网节点上运行的一组进程可以在该节点内的一组处理器上重新分发和运行。由[Tanenbaum 89]描述的计算服务器可以很容易地用这种硬件实现。
对于嵌入式应用,最小QNX系统可以放入少于100K的ROM(微内核、Proc和一些应用程序)中。通过添加Net进程和Net驱动程序(大约35K),嵌入式系统可以连接到更大的网络,成为更大的LAN的无缝扩展。这将允许嵌入式系统访问数据库、图形用户界面、LAN网关和其他服务。尽管嵌入式系统的功能有限,但是连接到LAN的网络为在嵌入式系统上运行的进程提供了对整个LAN上的资源的访问。嵌入式系统也可以从LAN引导,进一步减少ROM的需求。由于系统调试服务是通过运行着被调试程序的结点上的Proc进程的标准消息实现的,所以从LAN上的任何其他结点,都可以调试嵌入式系统上的应用程序。
为了承载标准传输协议,可以使用Net和网络驱动程序提供的与克拉克森兼容的(Clarkson-compatible)原始数据包传递服务。通过以这种方式实现的协议栈,同一物理LAN上的非QNX机器可以通过协议栈与之进行通信,访问多处理器QNX LAN的服务。在外界(如TCP/IP)看来,QNX环境是一个单一的多处理器机器。
目前,FLEET不支持网络桥接。这要求对未连接到公共网络的节点之间的通信,将需要使用中间代理进程将消息从LAN传递到LAN。目前正在研究如何定义一个路由进程,该进程作为Net的一个附件运行,以执行此功能。
可维护性
维护单内核操作系统的一个基本问题是,所有内核代码都在一个公共的共享地址空间中运行。内核的一部分可能会破坏另一部分的数据空间的危险是非常真实的,在每次将新驱动程序链接到内核时都必须加以考虑。QNX所采用的方法是显式地定义组成OS的组件之间的接口,这样每个资源管理器就像用户进程一样,在自己的内存保护空间中运行,OS模块之间的所有通信都是通过标准的系统IPC服务进行的。因此,由一个资源管理器引入的错误将被限制在该子系统,而不会损坏系统中其他不相关的资源管理器。
鉴于新的资源管理器和设备驱动程序,可以使用与用户进程相同的工具进行调试和分析,对系统的开发至少可以像应用程序开发一样有很好的指示。这一点非常重要,因为它给与了更大的自由来试验用新方法实现OS子系统,而不是付出巨大的努力用有限的工具来调试内核。
该体系结构还展示了其相对简单和易于实现的特性,对现有代码的维护是可管理的,并且添加新特性的任务是具有合理范围的。下表给出了组成QNX系统的各个模块的源代码行数和代码大小(本文中的所有源代码行数都是通过计算C源文件中的分号生成的)。
代码行数 | 代码大小 | |
Microkernel | 605 | 7KB |
Proc | 3924 | 52KB |
Fsys | 4457 | 57KB |
Fsys.ahascsi | 596 | 11KB |
Dev | 2204 | 23KB |
Dev.con | 1885 | 19KB |
Net | 1142 | 18KB |
Net.ether | 1117 | 17KB |
15930行 | 204KB |
尽管这两个系统的设计目标有些不同,但是源代码行数与[Pike 90]相比还是很不错的。
未来的发展方向
现在QNX已经与UNIX源代码兼容,二进制兼容性的开发正在进行中。源代码和二进制兼容性(ABI)的结合,将允许现有UNIX应用程序驻留在QNX运行时平台上,并受益于网络透明的分布式处理和增强的系统性能。
商业上成功的对称共享内存多处理器机器的出现,也提出了QNX微内核对多处理器支持问题。考虑到微内核的大小小于7K,多处理器支持的复杂性可以限制在系统中定义良好的部分,并有着健壮的实现。由于提供其余操作系统服务的资源管理器进程是多线程独立的进程,它们将继承微内核提供的多进程支持,而无需修改,操作系统的各个组件将实现真正的并发。
性能
QNX必须满足的一个必要挑战是来自主要关注实时应用程序的客户群的性能需求。尽管优雅的操作系统架构是一件令人愉快的工作,但“学术优雅”并不一定会创造一个商业上成功的操作系统——它还必须提供比传统的单内核操作系统更好的性能。当前许多微内核操作系统的设计目标是尝试匹配单内核系统的性能[Guillemont 91]。考虑到当前的单内核系统,如UNIX SVR4,不能提供硬件的全部性能(附录B),仅匹配这种性能级别将不能为操作系统技术的使用者,提供使用基于微内核的系统的显著优势。就像RISC处理器一样,在一项新技术能够提供明显的性能优势之前,它对最终用户来说只是一个架构细节,而不是影响购买决策的因素。
为了使QNX将硬件的全部性能交付到应用程序级别(并超过单内核操作系统的性能),开发了许多体系结构上的创新。对于这些增强的必要前提是不损害实时系统性能。尽管增加消息传递模型的通用性,在最初的研究中可能表明它比单内核有更多的开销,但是有许多架构思想可以纠正这种误解。对整个系统性能有重要贡献的两个概念,是直接在资源管理器中支持中断处理程序,以及多部件消息传递原语。
附录B包含执行类似操作的戴尔UNIX SVR4 v2.1实现和QNX 4.1实现的性能结果。选择戴尔UNIX是因为其SVR4产品,移植到Intel 80x86体系结构的良好性能。在第一部分中,我们比较了一个典型的UNIX内核调用(umask)的时间,但是在QNX下,umask()的实现实际上是作为一个消息发给Proc的。umask()的QNX系统调用速率大约是UNIX的三分之一,因为这些调用表示QNX和UNIX的执行顺序不同。执行序列如下:
1) 测试程序在内核中调用Send()
2) 内核调度Proc运行
3) 上下文切换到Proc
4) Proc从被阻塞的Receive()调用返回
5) Proc处理请求
6) Proc调用内核中的Reply()
7) 内核安排运行测试程序
8) 测试程序从Send()内核调用返回
实际上,QNX做了两个内核调用、两个消息传递、两次执行调度代码,并在UNIX系统执行三个内核调用所需的时间内执行两个上下文切换。在此过程中,可以在两个时间点调度其他进程,而不仅仅是在系统定时器间隔上调度。一个明显的优化可能是向微内核添加更多的内核调用。但是,请注意,这些操作通常不是系统级性能的瓶颈。这些调用作为消息保留给Proc的另一个优点是它们是网络透明的,可以从网络上的任何处理器调用。
Yield()调用是在QNX下的一个真正的内核调用,附录B中的结果显示内核调用速率是UNIX内核的三倍多。虽然在微内核中实现本报告中测量的其他调用,有着更快的内核调用次数,但是由于这些调用不是系统的性能瓶颈,因此没有迫切的需要去扩展内核以适应它们。此外,微内核的复杂性越大,对内核的调用就会变得越慢,直到微内核成长为一个单内核,这也意味着所有的限制。
在系统性能级别上,对于IPC、管道I/O和磁盘I/O,我们看到QNX的性能明显优于UNIX系统。事实上,QNX系统能够向应用程序提供几乎全部的原始设备吞吐量,而SVR4系统则相去甚远。对于磁盘I/O, QNX比SVR4快得多。随着速度更快的外围设备的出现,为了能够交付硬件的全部性能给一类应用程序,UNIX的内核开销将可能无法适应,除非对处理器性能进行更大的投资。在网络的情况下,QNX Net进程及其驱动程序将几乎整个电缆带宽交付给应用程序,即使只使用性能一般的机器。
结论
通过在实现和分析QNX微内核体系结构所获得的经验表明,微内核系统在为应用程序提供兼容API的同时,可以比单内核系统表现得更好,并提供更强大的功能。现有的应用程序源代码继续保持不变,而对操作系统的扩展的开发变得容易得多。操作系统平台的灵活性也为实现更大的多样性和更容易对操作系统特性做替代试验铺平了道路。正如RISC处理器架构的创新,在计算机硬件中产生了一系列新的性能能力一样,微内核操作系统架构将在操作系统技术中产生新的性能和功能标准的复兴。
参考文献
[Guillemont 91] M. Guillemont, J. Lipkis, D. Orr, and M. Rozier. A Second-Generation Micro-Kernel Based UNIX: Lessons in Performance and Compatibility. Proceedings of the Usenix Winter’91 Conference, Dallas, January 21-25, 1991, pp. 13-22
[Pike 90] Rob Pike, Dave Presotto, Ken Thompson, and Howard Trickey. Plan 9 from Bell Labs. Proceedings of the Summer 1990 UKUUG Conference, London, July, 1990, pp. 1-9
[Presotto 91] Dave Presotto, Rob Pike, Ken Thompson, and Howard Trickey. Plan 9, A Distributed System. Proceedings of the Spring 1991 EurOpen Conference, Tromso, May, 1991, pp. 43-50
[Tanenbaum 89] Andrew Tanenbaum, Rob van Renesse, and Hans van Staveren. A Retrospective and Evaluation of the Amoeba Distributed Operating System. Technical Report, Vrije University, Amsterdam, October, 1989, pp. 27
附录A
Til中断延迟
Tint中断处理时间
Tiret中断结束时间
中断处理简单的结束。时间是基于保护模式下的20MHz 386处理器测量的。
Til中断延迟
Tint中断处理时间
Tsl调度延迟
中断处理结束并触发代理。时间是基于保护模式下的20MHz 386处理器测量的。
中断和进程延迟
处理器 | 典型中断延迟 (Til) | 中断结束时间 (Tiret) | 调度延迟 (Tsl) | 上下文切换 |
33 MHz 486 | 6 微秒 | 5微秒 | 14微秒 | 17微秒 |
25 MHz 486 | 8 微秒 | 7微秒 | 18微秒 | 22微秒 |
33 MHz 386 | 11 微秒 | 10微秒 | 27微秒 | 33微秒 |
20 MHz 386 | 19 微秒 | 17微秒 | 45微秒 | 55微秒 |
16 MHz 386SX | 32 微秒 | 29微秒 | 77微秒 | 94微秒 |
8 MHz 286 | 65 微秒 | 59微秒 | 163微秒 | 188微秒 |
附录B
QNX4.1和SVR4 UNIX的系统性能参数对比
硬件环境:
处理器: | Intel 80486 33MHz,ISA总线 | |
缓存: | 片上8KB,片外0KB | |
内存: | 16MB | |
硬盘: | 1.2GB Micropolis SCSI硬盘 | |
控制器: | Adaptec 1542B |
软件环境:
QNX基准测试使用带有管道管理器的QNX4.1的默认安装。
UNIX基准测试使用DELL SVR4 v2.1 UNIX的默认安装。
QNX和DELL UNIX都是在多用户模式下运行的。QNX系统使用固定的2MB大小的缓存,DELL系统使用SVR4默认的缓存算法。
结果:
内核调用:
QNX | UNIX | Ratio | |||
umask | umask()系统调用(umask调用数每秒) | 10560 | 28743 | 0.37 | |
Yield | Yield()系统调用(yield调用数每秒) | 99760 | n/a | 3.49 | ① |
message | 消息传递(消息数每秒) | 26296 | 1887 | 13.9 | ② |
① | 由于Yield()调用是在POSIX 1003.4中定义的,并且在DELL UNIX下不受支持,因此我们假设如果它受到支持,UNIX内核将能够像umask()调用一样快速地执行它。这个假设使我们能够计算出一个比较的比率。QNX下的Yield()内核调用的实现方式与UNIX中的umask()内核调用大致相当,可以很好地比较内核入口开销。 |
② | QNX使用它的原生Send()/Receive()/Reply()消息传递原语,而UNIX使用它的标准消息传递工具。 |
管道I/O:
块大小 | QNX | UNIX | Ratio |
1024字节(字节每秒) | 1948398 | 916598 | 0.37 |
16384字节(字节每秒) | 3886920 | 2114722 | 3.49 |
顺序文件I/O:
使用8192字节的read()和write() 系统调用,写入一个16MB的文件,然后再读出来。在UNIX UFS和S5-1K两种文件系统上进行了测试。
QNX | UNIX UFS | Ratio | |
读(字节每秒) | 1430404 | 289811 | 4.94 |
写(字节每秒) | 777875 | 262513 | 2.96 |
QNX | UNIX S5-1K | Ratio | |
读(字节每秒) | 1430404 | 175200 | 8.16 |
写(字节每秒) | 777875 | 60068 | 12.95 |
QNX网络吞吐量
测量从一个节点上的用户进程,通过私有的两节点网络,到第二个节点上的用户进程的数据传输速率。每个节点都是33MHz 386计算机。
Arcnet令牌总线理论最大值: | 200,800 字节每秒 | 2.5兆比特每秒 |
单令牌总线 | 190,000 字节每秒 | 95%的效率 |
双令牌总线 | 380,000 字节每秒 | 95%的效率 |
以太网理论最大值: | 1,185,840 字节每秒 | 10兆比特每秒 |
以太网 | 960,000 字节每秒 | 81%的效率 |
熟悉此类处理器在以太网上NFS的传输速率的读者,肯定会喜欢这些性能数据。
原文链接:
https://cseweb.ucsd.edu/~voelker/cse221/papers/qnx-paper92.pdf
翻译链接:
https://mp.weixin.qq.com/s?__biz=MzIxMTcxNjcyOA==&mid=2247483843&idx=1&sn=10ec805c0156c4bf8a8cfab7ddfc31e1&chksm=97505ed4a027d7c253adfb324aefbe3a75d50e3fb7618e39656c9d22786ccb730a6c2c78472a&token=635484106&lang=zh_CN#rd
最后
以上就是感动溪流为你收集整理的QNX的体系架构概述QNX的体系架构概述的全部内容,希望文章能够帮你解决QNX的体系架构概述QNX的体系架构概述所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复