2009年5月30日星期六

理解Linux的性能

项目中常遇到需要对目前运行的系统进行效率分析,或碰到客户咨询如何优化系统的效率问题。更多的情况是,在系统出现问题的时候,需要分析原因,定位系统故障或瓶颈,当然,最好是可以一并解决故障。但实际上,操作系统优化是一个非常复杂的问题,况且linux有自己一套有别于其他操作系统管理的机制,由此会引起很多不必要的误解和麻烦。自问我是写不错条理性的文章了,只能转一份高人写的文档供参考。(文章根据实际进行了一定的裁减,并对容易碰到的问题做了标识)
一、前提
我们可以在文章的开始就列出一个列表,列出可能影响Linux操作系统性能的一些调优参数,但这样做其实并没有什么价值。因为性能调优是一个非常困难的任务,它要求对硬件、操作系统、和应用都有着相当深入的了解。如果性能调优非常简单的话,那些我们要列出的调优参数早就写入硬件的微码或者操作系统中了,我们就没有必要再继续读这篇文章了。正如下图所示,服务器的性能受到很多因素的影响。

当面对一个使用单独IDE硬盘的,有20000用户的数据库服务器时,即使我们使用数周时间去调整I/O子系统也是徒劳无功的,通常一个新的驱动或者应用程序的一个更新(如SQL优化)却可以使这个服务器的性能得到明显的提升。正如我们前面提到的,不要忘记系统的性能是受多方面因素影响的。理解操作系统管理系统资源的方法将帮助我们在面对问题时更好的判断应该对哪个子系统进行调整。
二、Linux的CPU调度
任何计算机的基本功能都十分简单,那就是计算。为了实现计算的功能就必须有一个方法去管理计算资源、处理器和计算任务(也被叫做线程或者进程)。非常感谢Ingo Molnar,他为Linux内核带来了O(1)CPU调度器,区别于旧有的O(n)调度器,新的调度器是动态的,可以支持负载均衡,并以恒定的速度进行操作。
新调度器的可扩展性非常好,无论进程数量或者处理器数量,并且调度器本身的系统开销更少。新调取器的算法使用两个优先级队列。
引用
·活动运行队列
·过期运行队列

调度器的一个重要目标是根据优先级权限有效地为进程分配CPU 时间片,当分配完成后它被列在CPU的运行队列中,除了 CPU 的运行队列之外,还有一个过期运行队列。当活动运行队列中的一个任务用光自己的时间片之后,它就被移动到过期运行队列中。在移动过程中,会对其时间片重新进行计算。如果活动运行队列中已经没有某个给定优先级的任务了,那么指向活动运行队列和过期运行队列的指针就会交换,这样就可以让过期优先级列表变成活动优先级的列表。通常交互式进程(相对与实时进程而言)都有一个较高的优先级,它占有更长的时间片,比低优先级的进程获得更多的计算时间,但通过调度器自身的调整并不会使低优先级的进程完全被饿死。新调度器的优势是显著的改变Linux内核的可扩展性,使新内核可以更好的处理一些有大量进程、大量处理器组成的企业级应用。新的O(1)调度器包含仔2.6内核中,但是也向下兼容2.4内核。

新调度器另外一个重要的优势是体现在对NUMA(non-uniform memory architecture)和SMP(symmetric multithreading processors)的支持上,例如INTEL@的超线程技术。
改进的NUMA支持保证了负载均衡不会发生在CECs或者NUMA节点之间,除非发生一个节点的超出负载限度。
三、Linux的内存架构
今天我们面对选择32位操作系统还是64位操作系统的情况。对企业级用户它们之间最大的区别是64位操作系统可以支持大于4GB的内存寻址。从性能角度来讲,我们需要了解32位和64位操作系统都是如何进行物理内存和虚拟内存的映射的。

在上面图示中我们可以看到64位和32位Linux内核在寻址上有着显著的不同。
在32位架构中,比如IA-32,Linux内核可以直接寻址的范围只有物理内存的第一个GB(如果去掉保留部分还剩下896MB),访问内存必须被映射到这小于1GB的所谓ZONE_NORMAL空间中,这个操作是由应用程序完成的。但是分配在ZONE_HIGHMEM中的内存页将导致性能的降低。
在另一方面,64位架构比如x86-64(也称作EM64T或者AMD64)。ZONE_NORMAL空间将扩展到64GB或者128GB(实际上可以更多,但是这个数值受到操作系统本身支持内存容量的限制)。正如我们看到的,使用64位操作系统我们排除了因ZONE_HIGHMEM部分内存对性能的影响的情况。
实际中,在32位架构下,由于上面所描述的内存寻址问题,对于大内存,高负载应用,会导致死机或严重缓慢等问题。虽然使用hugemen核心可缓解,但采取x86_64架构是最佳的解决办法。
四、虚拟内存管理
因为操作系统将内存都映射为虚拟内存,所以操作系统的物理内存结构对用户和应用来说通常都是不可见的。如果想要理解Linux系统内存的调优,我们必须了解Linux的虚拟内存机制。应用程序并不分配物理内存,而是向Linux内核请求一部分映射为虚拟内存的内存空间。如下图所示虚拟内存并不一定是映射物理内存中的空间,如果应用程序有一个大容量的请求,也可能会被映射到在磁盘子系统中的swap空间中。

另外要提到的是,通常应用程序不直接将数据写到磁盘子系统中,而是写入缓存和缓冲区中。Bdflush守护进程将定时将缓存或者缓冲区中的数据写到硬盘上。
Linux内核处理数据写入磁盘子系统和管理磁盘缓存是紧密联系在一起的。相对于其他的操作系统都是在内存中分配指定的一部分作为磁盘缓存,Linux处理内存更加有效,默认情况下虚拟内存管理器分配所有可用内存空间作为磁盘缓存,这就是为什么有时我们观察一个配置有数G内存的Linux系统可用内存只有20MB的原因。
同时Linux使用swap空间的机制也是相当高效率的,如上图所示虚拟内存空间是由物理内存和磁盘子系统中的swap空间共同组成的。如果虚拟内存管理器发现一个已经分配完成的内存分页已经长时间没有被调用,它将把这部分内存分页移到swap空间中。经常我们会发现一些守护进程,比如getty,会随系统启动但是却很少会被应用到。这时为了释放昂贵的主内存资源,系统会将这部分内存分页移动到swap空间中。上述就是Linux使用swap空间的机制,当swap分区使用超过50%时,并不意味着物理内存的使用已经达到瓶颈了,swap空间只是Linux内核更好的使用系统资源的一种方法。
简单理解:Swap usage只表示了Linux管理内存的有效性。对识别内存瓶颈来说,Swap In/Out才是一个比较又意义的依据,如果Swap In/Out的值长期保持在每秒200到300个页面通常就表示系统可能存在内存的瓶颈。下面的事例是好的状态:
引用
# vmstat
procs -----------memory------------- ---swap-- -----io---- --system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
1 0 5696 6904 28192 50496 0 0 88 117 61 29 11 8 80 1

五、模块化的I/O调度器
就象我们知道的Linux2.6内核为我们带来了很多新的特性,这其中就包括了新的I/O调度机制。旧的2.4内核使用一个单一的I/O调度器,2.6内核为我们提供了四个可选择的I/O调度器。因为Linux系统应用在很广阔的范围里,不同的应用对I/O设备和负载的要求都不相同,例如一个笔记本电脑和一个10000用户的数据库服务器对I/O的要求肯定有着很大的区别。
引用
(1).Anticipatory
anticipatory I/O调度器创建假设一个块设备只有一个物理的查找磁头(例如一个单独的SATA硬盘),正如anticipatory调度器名字一样,anticipatory调度器使用“anticipatory”的算法写入硬盘一个比较大的数据流代替写入多个随机的小的数据流,这样有可能导致写I/O操作的一些延时。这个调度器适用于通常的一些应用,比如大部分的个人电脑。
(2).Complete Fair Queuing (CFQ)
Complete Fair Queuing(CFQ)调度器是Red Flag DC Server 5使用的标准算法。CFQ调度器使用QoS策略为系统内的所有任务分配相同的带宽。CFQ调度器适用于有大量计算进程的多用户系统。它试图避免进程被饿死和实现了比较低的延迟。
(3).Deadline
deadline调度器是使用deadline算法的轮询的调度器,提供对I/O子系统接近实时的操作,deadline调度器提供了很小的延迟和维持一个很好的磁盘吞吐量。如果使用deadline算法请确保进程资源分配不会出现问题。
(4).NOOP
NOOP调度器是一个简化的调度程序它只作最基本的合并与排序。与桌面系统的关系不是很大,主要用在一些特殊的软件与硬件环境下,这些软件与硬件一般都拥有自己的调度机制对内核支持的要求很小,这很适合一些嵌入式系统环境。作为桌面用户我们一般不会选择它。

六、网络子系统
新的网络中断缓和(NAPI)对网络子系统带来了改变,提高了大流量网络的性能。Linux内核在处理网络堆栈时,相比降低系统占用率和高吞吐量更关注可靠性和低延迟。所以在某些情况下,Linux建立一个防火墙或者文件、打印、数据库等企业级应用的性能可能会低于相同配置的Windows服务器。
在传统的处理网络封包的方式中,如下图蓝色箭头所描述的,一个以太网封包到达网卡接口后,如果MAC地址相符合会被送到网卡的缓冲区中。网卡然后将封包移到操作系统内核的网络缓冲区中并且对CPU发出一个硬中断,CPU会处理这个封包到相应的网络堆栈中,可能是一个TCP端口或者Apache应用中。

这是一个处理网络封包的简单的流程,但从中我们可以看到这个处理方式的缺点。正如我们看到的,每次适合网络封包到达网络接口都将对CPU发出一个硬中断信号,中断CPU正在处理的其他任务,导致切换动作和对CPU缓存的操作。你可能认为当只有少量的网络封包到达网卡的情况下这并不是个问题,但是千兆网络和现代的应用将带来每秒钟成千上万的网络数据,这就有可能对性能造成不良的影响。
正是因为这个情况,NAPI在处理网络通讯的时候引入了计数机制。对第一个封包,NAPI以传统的方式进行处理,但是对后面的封包,网卡引入了POLL的轮询机制:如果一个封包在网卡DMA环的缓存中,就不再为这个封包申请新的中断,直到最后一个封包被处理或者缓冲区被耗尽。这样就有效的减少了因为过多的中断CPU对系统性能的影响。同时,NAPI通过创建可以被多处理器执行的软中断改善了系统的可扩展性。NAPI将为大量的企业级多处理器平台带来帮助,它要求一个启用NAPI的驱动程序。在今天很多驱动程序默认没有启用NAPI,这就为我们调优网络子系统的性能提供了更广阔的空间。
七、理解Linux调优参数
因为Linux是一个开源操作系统,所以又大量可用的性能监测工具。对这些工具的选择取决于你的个人喜好和对数据细节的要求。所有的性能监测工具都是按照同样的规则来工作的,所以无论你使用哪种监测工具都需要理解这些参数。下面列出了一些重要的参数,有效的理解它们是很有用处的。
(1)处理器参数
引用
·CPU utilization
这是一个很简单的参数,它直观的描述了每个CPU的利用率。在xSeries架构中,如果CPU的利用率长时间的超过80%,就可能是出现了处理器的瓶颈。
·Runable processes
这个值描述了正在准备被执行的进程,在一个持续时间里这个值不应该超过物理CPU数量的10倍,否则CPU方面就可能存在瓶颈。
·Blocked
描述了那些因为等待I/O操作结束而不能被执行的进程,Blocked可能指出你正面临I/O瓶颈。
·User time
描述了处理用户进程的百分比,包括nice time。如果User time的值很高,说明系统性能用在处理实际的工作。
·System time
描述了CPU花费在处理内核操作包括IRQ和软件中断上面的百分比。如果system time很高说明系统可能存在网络或者驱动堆栈方面的瓶颈。一个系统通常只花费很少的时间去处理内核的操作。
·Idle time
描述了CPU空闲的百分比。
·Nice time
描述了CPU花费在处理re-nicing进程的百分比。
·Context switch
系统中线程之间进行交换的数量。
·Waiting
CPU花费在等待I/O操作上的总时间,与blocked相似,一个系统不应该花费太多的时间在等待I/O操作上,否则你应该进一步检测I/O子系统是否存在瓶颈。
·Interrupts
Interrupts值包括硬Interrupts和软Interrupts,硬Interrupts会对系统性能带来更多的不利影响。高的Interrupts值指出系统可能存在一个软件的瓶颈,可能是内核或者驱动程序。注意Interrupts值中包括CPU时钟导致的中断(现代的xServer系统每秒1000个Interrupts值)。

(2)内存参数
引用
·Free memory
相比其他操作系统,Linux空闲内存的值不应该做为一个性能参考的重要指标,因为就像我们之前提到过的,Linux内核会分配大量没有被使用的内存作为文件系统的缓存,所以这个值通常都比较小。
·Swap usage
这个值描述了已经被使用的swap空间。Swap usage只表示了Linux管理内存的有效性。对识别内存瓶颈来说,Swap In/Out才是一个比较又意义的依据,如果Swap In/Out的值长期保持在每秒200到300个页面通常就表示系统可能存在内存的瓶颈。
·Buffer and cache
这个值描述了为文件系统和块设备分配的缓存。在Red Flag DC Server 5版本中,你可以通过修改/proc/sys/vm中的page_cache_tuning来调整空闲内存中作为缓存的数量。
·Slabs
描述了内核使用的内存空间,注意内核的页面是不能被交换到磁盘上的。
·Active versus inactive memory
提供了关于系统内存的active内存信息,Inactive内存是被kswapd守护进程交换到磁盘上的空间。

(3)网络参数
引用
·Packets received and sent
这个参数表示了一个指定网卡接收和发送的数据包的数量。
·Bytes received and sent
这个参数表示了一个指定网卡接收和发送的数据包的字节数。
·Collisions per second
这个值提供了发生在指定网卡上的网络冲突的数量。持续的出现这个值代表在网络架构上出现了瓶颈,而不是在服务器端出现的问题。在正常配置的网络中冲突是非常少见的,除非用户的网络环境都是由hub组成。
·Packets dropped
这个值表示了被内核丢掉的数据包数量,可能是因为防火墙或者是网络缓存的缺乏。
·Overruns
Overruns表达了超出网络接口缓存的次数,这个参数应该和packets dropped值联系到一起来判断是否存在在网络缓存或者网络队列过长方面的瓶颈。
·Errors
这个值记录了标志为失败的帧的数量。这个可能由错误的网络配置或者部分网线损坏导致,在铜口千兆以太网环境中部分网线的损害是影响性能的一个重要因素。

(4)块设备参数
引用
·Iowait
CPU等待I/O操作所花费的时间。这个值持续很高通常可能是I/O瓶颈所导致的。
·Average queue length
I/O请求的数量,通常一个磁盘队列值为2到3为最佳情况,更高的值说明系统可能存在I/O瓶颈。
·Average wait
响应一个I/O操作的平均时间。Average wait包括实际I/O操作的时间和在I/O队列里等待的时间。
·Transfers per second
描述每秒执行多少次I/O操作(包括读和写)。Transfers per second的值与kBytes per second结合起来可以帮助你估计系统的平均传输块大小,这个传输块大小通常和磁盘子系统的条带化大小相符合可以获得最好的性能。
·Blocks read/write per second
这个值表达了每秒读写的blocks数量,在2.6内核中blocks是1024bytes,在早些的内核版本中blocks可以是不同的大小,从512bytes到4kb。
·Kilobytes per second read/write
按照kb为单位表示读写块设备的实际数据的数量。

八、附录
本文截取和修改自IBM的红皮书Tuning Red Hat Enterprise Linux on IBM eServer xSeries Servers。

工作面试时最难的25个问题

简介:工作面试时最难的25个问题,很好的准备是成功的一半。如果你是一个对目前的职位不满意,正着手去在新的一年里找到一个新的职位,这篇文章就是你的一个帮手。工作面试是你去面对未来的老板的征途中最重要的一个过程。你必须像进行一个击剑锦标赛或着一个国际象棋比赛那样的坚韧和敏捷来对待面试。
准备是成功的一半如果你是一个对目前的职位不满意,正着手去在新的一年里找到一个新的职位,这篇文章就是你的一个帮手。工作面试是你去面对未来的老板的征途中最重要的一个过程。你必须像进行一个击剑锦标赛或着一个国际象棋比赛那样的坚韧和敏捷来对待面试。
本文是从 Wiiam J. Min和James . abea
的"在失业的时候如何生存并成功的找到另一个工作"一文中摘选出来的。版权所有:Dake
Beam Min, in;出版:Haut Bae Jvanvih。
Min是纽约的Dake Beam
Min公司的董事长,abea是该公司的主席。该公司是国家主要的新职介绍公司,办公所在地在费城。
1.介绍你自己
这个问题通常是一个面试的开始的第一个问题,要额外的小心不要滔滔不绝。尽可能的让你的回答在一分钟,最多2分钟的时间内结束。你的回答应该包含以下4个主题:早期生活,教育背景,工作背景以及最近的工作经验。要着重强调最后的那个主题。要牢记这个问题通常是一个热身的问题,不要把你的最重要的观点浪费在这个问题上。
2.你对我们公司有什么样的了解
你必须能够谈论关于这个公司的产品,服务,收入,业界声望,形象,目标,存在的问题,管理风格,职工,历史和企业文化等问题。但是不要表现出你对这个公司的一切都了如指掌。让你的回答能够体现出你对该公司做了一些研究,但是不要让面试官被你打败(vewhem),并表现出你希望能够了解关于公司更多的情况。
你可以用这样的态度来开始回答问题:"在我的寻找工作的过程中,我调查研究了很多公司,出于如下的理由,贵公司是我感兴趣的公司之一:"。
用一个积极的态度来回答这个问题,不要这样说:"每个人都告诉我这个公司处于困境中,有各种样的麻烦,这就是我来这儿的原因",即是那的确是你在这儿的理由。
3.为什么你希望来我们公司工作?
最糟糕的答案就是"因为我喜欢人"。要是你喜欢的是动物,那你去哪工作呢?在这个问题的回答上,并且贯穿整个面试的过程中,一个优秀的答案总是来自于你所作的调查研究,这样的话你可以从公司的需要那个方面来回答。你可能说你的研究表明这个公司所做的工作正是你说希望参与的,并且他们做这个工作的方式极大的吸引了你。例如,如果这个公司由于强大的管理而著称,纳闷你的答案可以提到这个事实,并表示你希望成为这个小组的一员。如果这个公司着重强调研发,那么就强调你希望创造你的事物,而你知道这个公司非常鼓励这样的行为。如果这个公司强调经济控制,你的答案就应该包含对数字的热爱。
如果你觉得你必须捏造一个答案,例如如果这个公司强调研发,但是你觉得你必须提到这一点而实际上你对这根本不感兴趣,那么你可能根本不应该参加这个面试,因为你可能根本不会考虑在这个公司工作。
你的之前的准备必须包括对这个公司做详尽的了解,来避免到一个你无法发挥才干或者根本不想去的公司面试。大多数人都不擅长说谎,所以在面试中欺瞒面试官是一件很困难的事情。即使你成功的做到了这一点,你所获得的也只是一个你不想参加的工作
4.你可以为我们完成哪些其他人做不到的事情?
这个问题上,你有权利或者是义务来自吹自擂。谈论一些你完成工作的记录,提到你简历中的独特之处,或者列出你职业生涯中的成就。告诉别人,你的技能和兴趣在获取这些结果的过程中发挥了很大的作用,并使得你很有价值。提到你能够合理的安排工作优先顺序,找出问题,并利用你的经验和精力来解决问题。
5.你觉得这个职位最吸引你的地方是什么?最不吸引你的地方又是什么?
列出3到4个这个工作吸引人的方面,然后提出一个简单的不重要的不吸引人的问题。
6.为什么我们应该雇佣你?
参见问题4, 考虑你的能力,你的工作经历和你的干劲。
7.你希望在工作中能够获得什么?
让你的答案来源与这个公式提供的机会。谈论你希望能够大展身手并获取认可的要求。让你的答案基于工作机会而不是个人的要求
8.谈论一下你对你应聘的这个职位的定义
你的答案应该简短并且是基于工作要求的。考虑这个工作的责任和义务。在你回答问题之前确定你真正的了解这个职位所涉及的方方面面。如果你不确定,就去问面试官,他可能会帮你回答这个问题。
9.你需要多久能够对公司做出显著的贡献?
答案要实际一点。可以这样回答,尽管你希望从第一天开始就能够满足公司紧迫的要求,并开始发挥作用,但是你可能需要6个月到1年的时间来足够了解这个公司及其需要来做出很大的贡献。
10.你会在公司工作多久?
可以这样回答,你对在这个公司的职业生涯很感兴趣,可是也得承认你必须能够不断感觉到有挑战才能够继续在任何公司呆着。可以考虑这样的语句"只要我们双方都感觉有收获"。
11.你的简历显示你的能力超出了这个工作的要求,你是如何认为的?
强调你对在这个公司开始一个长期的合作的兴趣,你可以说你认为如果你在这个职位上表现的很好,公司还会为你提供新的机会。也要提到一个好公司需要好的职员。有检验的职员总会有很好的奖励;既然你是如此的很是这个职位,雇主将会很快从他的投资中获得回报。一个发展中的,充满活力的工资永远不会嫌天才多的。
12.你的管理方式是什么样的?
你必须对这个公司的风格有足够的了解,这样才能让你的管理风格对其进行补充。可能的风格包括:基于任务的(我喜爱问题-研究那些是错误的,选择一个解决方案并完成),基于结构的(我做出的任何一个管理的决定是基于它是如何影响问题的底线的),或者是家长式作风的(我致力与管理好我的每一个下属,并给他们指引正确的方向)。
民主参与式的风格是目前比较流行的一种:一个开放的管理方式,通过激励手下并根据所负责的事情分派任务来完成每一件事情。
当你考虑这个问题的时候,要思考你的风格是否会让你在这个公司里高兴并有效率的工作。
13.你是一个合格的经理吗?你可以举一些例子吗?你是否觉得你有顶级管理人员的潜力?
保证你的答案是基于成果和任务的。通过你职业生涯中的一些例子来加固你的论点。强调你的经验和精力
14.当你招聘人手的时候你需要什么类型的?
考虑一些技能方面的问题。主动性,以及能够舒服和有效的与其他人一起工作的适应性。提到你希望雇佣一些看起来能够在公司中获得提升的人。
15.你是否曾经不得不解雇一些员工?是什么理由?你是如何解决这个情况的?
要承认这个情况不是容易解决的,但是你还是很好的解决了,不管是从公司角度还是从个人角度。让他们知道,和其他人一样,你不喜欢这种让人不乐意的工作,但是你可以有效的富有人情味的解决问题,尤其是在要解雇某个人的时候。
16.你认为作为一个经理或者高级行政人员最困难的事情是什么?
要提到指定计划,指定和成本控制。最困难的任务是要去激发并管理雇员来完成一些计划中的事情,并且按时的在预算范围内完成任务。
17.在我们这个行业中你觉得什么是最重要的趋势?
一样要准备两到三个趋势来阐明你对所在行业的是多么的了解。你可以需要考虑技术上的挑战或者机会,金融环境甚至管理的需求作为你所应该考虑收集的关于你的行业说面对的状况。
18.你为什么离开你现在的工作(上一个工作)?
在不伤害你自己的情况下要简明扼要并诚实的回答这个问题。回溯到你寻找工作的计划阶段,那时你正在把这个话题当作你的工作经历。如果你是在一次公司裁员中被裁掉的,直接说出来好了;否则的话,要指明这次离职是你自己的决定,你自己行动的结构,不要特到任何关于性格冲突等。
19.你觉得放弃原来所有的福利待遇等来寻找一个新的工作是什么感觉?
要提到你很自然的担心这一点,但是并不很恐慌。你愿意为寻找到合适的工作而冒一点风险。不要说,你对安全感比成功的完成工作更感兴趣。
20.在你上一份工作中,你最喜欢那个方面的特点?最不喜欢哪个?
要小心而计息的回答这个问题。要多说你喜欢的特性,而少说你不喜欢的。不要引用个人的问题。如果你使得你的上一份工作听起来很糟糕,面试官会疑问你为什么还能在上一份职位上一直待到现在。
21.你如何看待你的老板?
要尽可能积极的回答这个问题。你潜在的未来的老板很希望能够了解你未来在相似的场合会如何谈论他。
22.你在现在的年龄中为什么不能赚到更多?
要告诉他这是你寻找新的工作的理由之一,不要处于守势。
23.你希望这个职位的薪水是多少?
讨论薪水是一个很微妙的问题。[b]我们建议你在条件允许的情况下尽可能的拖延用一个精[/b]你可以说,"我知道这个工作的薪水的大概范围是¥---到¥---。这个对于我来说是合适的价位。"你也可以用一个问题来回答这个问题:
"你可能在这个问题上可以帮助我。你能否告诉我在公司中对相似职位的工作的大概薪水是多少?"。
如果你是在一个最初的面试中遇到这个问题,你可以说你觉得你需要更多的了解这个职位的职能才能够对这个问题有个有意思的回答。在这个问题上通过询问面试官或者人事高级主管或者自己去寻找结果,你可以尝试去获得这份工作是由有一个工资等级。如果有,并且你能够接受,那么直接回答你满意这个薪水范围好了。
如果面试官继续纠缠这个问题的话,你可以说"我现在的薪水是¥--。和其他人一样,我希望能够提升这个数字,但是我主要的兴趣还是在工作本身。"要记住,获取一个新的工作这件事本身不会使得你能够赚到更多的钱。
如果一个猎头公司也参与了此事的话,你的联系人可能可以帮助你解决这个薪水的问题。他甚至可以帮你介入此事。例如,如果他告诉你这个职位的待遇,然后你告诉他你现在已经赚那么多的,并且希望待遇能够适当的提升,他可能会去雇主那然后提议给你增加10%的待遇。
如果没有获得关于这个职位的合适的信息,而面试官还继续这个话题的话,你可以用一个具体的数字来回答这个问题。你不能给别人留下待遇完全没有影响你将会接受任何待遇的印象。如果你年薪8W的话,你不可能没有变现出放弃自己的时候,说3.5W一年也是可以接受的。(如果你是在做工作的一个彻底的变化的话,这种情况可能也是有道理,可以理解的)。
不要很快就把你自己卖掉:),但是要继续的强调这个工作本身才是你最看重的东西。面试官可能会去判断你希望从这个工作的待遇是多少哦。不要给面试官留下金钱对你来说是唯一重要的事情的感觉。把薪水的问题和工作本身挂钩。
但是无论合适可能的话,在你到面试过程的最后一个阶段之前,少谈论薪水的问题。到那个阶段的时候,你就应该知道,这个公司对你有很大的兴趣,这个时候在谈论薪水待遇的话就会有很大的余地了。
24.你长期的目标是什么?
回到你寻找工作的计划阶段。不要这样回答"我希望能够得到你广告中的工作"。把你的目标与你面试的公司关系起来,"在你们这样一个公司,我希望能够..."
25.你目前位置在工作中是多么的成功?
你要回答,总的来说你对你目前为止的职业生涯是很高兴很满意的。列举一些生活中普通的琐事,你觉得你完成的很好,没有怨言。

手工释放linux内存——/proc/sys/vm/drop_caches

总有很多朋友对于Linux的内存管理有疑问。而在新版核心中,似乎对这个问题提供了新的解决方法,特转出来给大家参考一下。最后,还附上我对这方法的意见,欢迎各位一同讨论。

当在Linux下频繁存取文件后,物理内存会很快被用光,当程序结束后,内存不会被正常释放,而是一直作为caching。这个问题,貌似有不少人在问,不过都没有看到有什么很好解决的办法。那么我来谈谈这个问题。

一、通常情况
先来说说free命令:
引用
[root@server ~]# free -m
total used free shared buffers cached
Mem: 249 163 86 0 10 94
-/+ buffers/cache: 58 191
Swap: 511 0 511

其中:
引用
total 内存总数
used 已经使用的内存数
free 空闲的内存数
shared 多个进程共享的内存总额
buffers Buffer Cache和cached Page Cache 磁盘缓存的大小
-buffers/cache 的内存数:used - buffers - cached
+buffers/cache 的内存数:free + buffers + cached

可用的memory=free memory+buffers+cached。

有了这个基础后,可以得知,我现在used为163MB,free为86MB,buffer和cached分别为10MB,94MB。
那么我们来看看,如果我执行复制文件,内存会发生什么变化.
引用
[root@server ~]# cp -r /etc ~/test/
[root@server ~]# free -m
total used free shared buffers cached
Mem: 249 244 4 0 8 174
-/+ buffers/cache: 62 187
Swap: 511 0 511

在我命令执行结束后,used为244MB,free为4MB,buffers为8MB,cached为174MB,天呐,都被cached吃掉了。别紧张,这是为了提高文件读取效率的做法。

为了提高磁盘存取效率,Linux做了一些精心的设计,除了对dentry进行缓存(用于VFS,加速文件路径名到inode的转换),还采取了两种主要Cache方式:Buffer
Cache和Page
Cache。前者针对磁盘块的读写,后者针对文件inode的读写。这些Cache有效缩短了
I/O系统调用(比如read,write,getdents)的时间。

那么有人说过段时间,linux会自动释放掉所用的内存。等待一段时间后,我们使用free再来试试,看看是否有释放?
引用
[root@server test]# free -m
total used free shared buffers cached
Mem: 249 244 5 0 8 174
-/+ buffers/cache: 61 188
Swap: 511 0 511

似乎没有任何变化。(实际情况下,内存的管理还与Swap有关)

那么我能否手动释放掉这些内存呢?回答是可以的!

二、手动释放缓存
/proc是一个虚拟文件系统,我们可以通过对它的读写操作做为与kernel实体间进行通信的一种手段。也就是说可以通过修改/proc中的文件,来对当前kernel的行为做出调整。那么我们可以通过调整/proc/sys/vm/drop_caches来释放内存。操作如下:
引用
[root@server test]# cat /proc/sys/vm/drop_caches
0

首先,/proc/sys/vm/drop_caches的值,默认为0。
引用
[root@server test]# sync

手动执行sync命令(描述:sync 命令运行 sync
子例程。如果必须停止系统,则运行sync 命令以确保文件系统的完整性。sync
命令将所有未写的系统缓冲区写到磁盘中,包含已修改的 i-node、已延迟的块 I/O
和读写映射文件)
引用
[root@server test]# echo 3 > /proc/sys/vm/drop_caches
[root@server test]# cat /proc/sys/vm/drop_caches
3

将/proc/sys/vm/drop_caches值设为3
引用
[root@server test]# free -m
total used free shared buffers cached
Mem: 249 66 182 0 0 11
-/+ buffers/cache: 55 194
Swap: 511 0 511

再来运行free命令,会发现现在的used为66MB,free为182MB,buffers为0MB,cached为11MB。那么有效的释放了buffer和cache。

◎ 有关/proc/sys/vm/drop_caches的用法在下面进行了说明
引用
/proc/sys/vm/drop_caches (since Linux 2.6.16)
Writing to this file causes the kernel to drop clean caches,
dentries and inodes from memory, causing that memory to become
free.

To free pagecache, use echo 1 > /proc/sys/vm/drop_caches; to
free dentries and inodes, use echo 2 > /proc/sys/vm/drop_caches;
to free pagecache, dentries and inodes, use echo 3 >
/proc/sys/vm/drop_caches.

Because this is a non-destructive operation and dirty objects
are not freeable, the user should run sync first.

三、我的意见
上述文章就长期以来很多用户对Linux内存管理方面的疑问,给出了一个比较"直观"的回复,我更觉得有点像是核心开发小组的妥协。
对于是否需要使用这个值,或向用户提及这个值,我是有保留意见的:
引用
1、从man可以看到,这值从2.6.16以后的核心版本才提供,也就是老版的操作系统,如红旗DC
5.0、RHEL 4.x之前的版本都没有;
2、若对于系统内存是否够用的观察,我还是原意去看swap的使用率和si/so两个值的大小;

用户常见的疑问是,为什么free这么小,是否关闭应用后内存没有释放?
但实际上,我们都知道这是因为Linux对内存的管理与Windows不同,free小并不是说内存不够用了,应该看的是free的第二行最后一个值:
引用
-/+ buffers/cache: 58 191

这才是系统可用的内存大小。
实际项目中告诉我们,如果因为是应用有像内存泄露、溢出的问题,从swap的使用情况是可以比较快速可以判断的,但free上面反而比较难查看。
相反,如果在这个时候,我们告诉用户,修改系统的一个值,"可以"释放内存,free就大了。用户会怎么想?不会觉得操作系统"有问题"吗?
所以说,我觉得既然核心是可以快速清空buffer或cache,也不难做到(这从上面的操作中可以明显看到),但核心并没有这样做(默认值是0),我们就不应该随便去改变它。
一般情况下,应用在系统上稳定运行了,free值也会保持在一个稳定值的,虽然看上去可能比较小。
当发生内存不足、应用获取不到可用内存、OOM错误等问题时,还是更应该去分析应用方面的原因,如用户量太大导致内存不足、发生应用内存溢出等情况,否则,清空buffer,强制腾出free的大小,可能只是把问题给暂时屏蔽了。

我觉得,排除内存不足的情况外,除非是在软件开发阶段,需要临时清掉buffer,以判断应用的内存使用情况;或应用已经不再提供支持,即使应用对内存的时候确实有问题,而且无法避免的情况下,才考虑定时清空buffer。(可惜,这样的应用通常都是运行在老的操作系统版本上,上面的操作也解决不了)。O(∩_∩)O哈哈~
visitor
2009/02/25 11:28
完全没必要这样做,即使内存全被cache满了,运行一个大程序试试,绝不会有什么"内存不足"的情况,需要多少内存就从cache释放多少内存。

cache的好处可以减少很多硬盘访问,我的一块老硬盘,用windows的时候每打开一个程序硬盘都要狂响一阵,和拖拉机有一比,但用linux的时候硬盘非常安静!
linuxing 回复于 2009/02/26 00:06
O(∩_∩)O哈哈~,可惜并不是每个人都明白linux这个问题,正如我最后说的:"我更觉得有点像是核心开发小组的妥协"。
但转这个帖子出来,也不是没有实际意义的。

Linux 图形现状

在淡出 Xgl 方面的工作之后,我仍收到大量 email
并阅读许多帖子。我的结论是大多数人并没有真正理解 linux
图形方面正在发生的事情。人们无法看清整体的图景,这是可以理解的。图形是一个庞杂的领域,包含着众多软件组件和相互竞争的开发小组。作为一种尝试,
我写了这篇文章,来解释所有这些部分是如何组织到一起的。
俱往矣

今年是 X server 的二十一岁生日。脱胎于 Athena 项目,自 1984
年发端以来,过去的那些年中,它很好地满足了 Unix 社团的需要。 X
已经被广泛应用,推动着今天的大多数 Linux 桌面。这篇 Wikipedia
文章2提供了更多详细资料,除了两项开源的主要 X
创新,它们允许提供跨平台支持和网络通透性。

然而,自 X 着手设计,20
年时光匆匆流逝,视频硬件今非昔比了。如果瞥一下一块现代视频芯片的架构图,你会注意到一个小小的标记着
2D 的区块。那是由于芯片的 90% 专注于 3D 管线。你正好为那些 3D
硬件付了费,因此如果桌面能利用它那不是很棒吗。很多人并未意识到 3D
硬件也可用于绘制 2D 桌面。看看你的屏幕,它是一块平平的 2D
平面,对不对?任何由 3D 硬件生成的图画最终都要显示在平的 2D
屏幕上。此一事实应能让你认识到,通过适当地编程,3D 硬件可以绘制 2D 桌面。
图形供应商

多年以前图形芯片供应商乐于为他们的硬件公开数据表和编程信息。但是随着专利库的增大,对专利侵权的恐惧也增大了。现在图形芯片供应商将关于芯片的全部信息秘而不宣,作为使专利持有人更难搜寻侵权行为的一种手段。至少这是供应商给出的隐藏编程规范的理由。并且他们也宣称隐藏编程规范可使竞争对手更难对他们的芯片做反相工程,但我对此同样持怀疑态度。所有这些隐藏规范使为这些芯片编写开源设备驱动异常困难。作为替代方案,我们被迫依赖供应商来为最新的硬件提供驱动程序。如果你尚未留意,请注意图形供应商的确仅仅关心
MS Windows 因此他们只为 Linux 提供最低程度的驱动支持。也有例外。Intel
为他们的部分芯片提供开源驱动。Nvidia/ATI 提供专有驱动,但是落后于 Windows
版本。总的后果是一批非常参差不齐的驱动,品质从良好到完全空白。
桌面选择

其它的桌面选择, Windows 与 Mac,都拥有 GPU
加速的桌面。它们明显地、眼见地比他们的前辈要好。某些情况下这些新的带加速的桌面的绘制速度能够比旧的模型快过一百倍。在未来的某个时候,图形芯片供应商会移除标记为
2D 的那个小点,仅给我们留下 3D 硬件。Microsoft 和 Apple
看起来已经得到信儿说 3D 是未来的方向并开始进行转换。另一方面。几个 X
开发者曾告诉我停止谈论竞争的图景。他们说他们想做的是让 X 更好。尽管 X
开发者可能无动于衷,我确信当由于缺乏竞争力的 GUI
而开始丧失份额的时候,Redhat 和 Novell 的经理们不会赞同此一观点。

在桌面上使用 3D 并不只是为了制造更华丽的视觉效果3。有大量利用 3D
能力生成的效果只是虚饰,但仍有些真正的理由运用 3D。简单来说 3D 快过
2D,没有人动手使他们的 2D 功能更快,所有的硅工程师都转向了 3D
。你能够完成快速、任意的图像处理,例如色彩空间转换,拉伸/卷曲,等等。我曾见过某些消耗主
CPU 几秒钟才完成一帧的超级复杂的过滤操作在 shader
硬件上以实时达成。支持任意色彩映射的不同的 Windows 色深(同时支持 8、16、24
位窗口)。为项目管理者提供极快的屏幕翻转/旋转,为视力不良者提供全屏缩放,等等。分辨率无关性允许对象以任意分辨率/尺寸渲染,当显示到屏幕上的时候再降低/提高取样精度。更多有意思的应用在后面讨论窗口化的小节里阐述。
当前的 X.org 服务器

X.org 即将发布 X11R74。这个发布的主要特性是 X
源代码库的模块化。尽管对大多数用户并无意义,模块化将使在 X
源代码上工作容易得多。模块化之前 X 源代码树包含约 16M
行代码,全部作为一个单独的项目构建。模块化之后,代码树将分解为一打左右的独立部分,使项目的构建和理解容易得多。
X,作为操作系统

X
究竟是一个应用程序还是一个操作系统?在这里有一份优秀的参考文献帮助我们理解一个
X server 是如何组织到一起的。尽管写成已有 8
年之久,大多数内容仍然切题。如果你不知道何谓 DIX、mi、DDX、CFB
什么的,最好先读读它。大概在 X11R6.3 那会儿 Xfree86 分裂了,X
服务器的设计变得极度跨平台。X
面向的众多操作系统对硬件侦测这类事情提供不同程度的支持。为了解决此类问题,X
添加了代码侦测 PCI 总线来搜寻硬件,代码搜寻视频 ROM
并运行它们来重置硬件,搜寻鼠标和键盘并提供驱动,管理多个 VGA
设备的问题,最后甚至提供它自己的模块加载器。这一步让 X
开始模糊了它是应用程序还是操作系统的界线。虽然某些操作环境的确需要这种类
OS 支持,实现这些特性来提供同样服务的操作系统,比如 Linux, 终于落到 X 和
OS
之间互相冲突的境地。当然操作系统是一个移动的标靶,十年前恰当的决策今天看来可能已经不合时宜了。

Linux 内核提供在 BSD 和某些其它平台上并不存在的子系统,比如 PCI 和
framebuffer。出于对跨平台支持的兴趣,X
服务器内建了和这些子系统平行的实现。在过去对此确有需求但在当前 Linux
系统上这导致两块不同的软件都试图控制同一个硬件。Linux 具有多个非 X
的视频硬件使用者,它们与 X
交互的唯一位置就是内核。内核提供了很多机制来协调这些使用者;反正就是 PCI
子系统,输入驱动,热拔插检测,设备驱动这档子事。为了和 Linux
一致,最佳方案是使用内核提供的特性,仅仅在其它平台上运行这些重复的库。Fbdev
和 XAA 驱动是冗余驱动的主要例子。

Linux
有一个优秀的热拔插系统,图形系统真的有必要开始利用它。显示屏可以从多个来源上热拔插。有一个传统的热拔插来源;有些人将新的显示卡插入热拔插背板。然而存在其它非传统的途径来获得一次热拔插。另一位用户可能正在使用你要加到你的屏幕组的显示屏,当他注销的时候你就会获得一次热拔插。你可以将一台外部监视器连接到笔记本电脑上,从而生成一次热拔插。你可以以无线方式通过
DMX 或 Chromium 这类东西连接到显示墙。USB
也是很多热拔插的来源。用户能够热拔插鼠标、手写板、键盘、音频设备、甚至图形适配器。既然不和内核的热拔插系统通信,当前
X 服务器不能处理这些情形中的任何一种。

标准的 Linux 桌面使用 rooted X。Rooted X 指的是 X
控制最上级桌面的绘制,窗口则处于它之上。 Cygwin/X,Directfb 和 Apple
Darwin 都是用 rootless
X。这些环境拥有另一套窗口系统负责显示。这些宿主窗口系统绘制主桌面并实现它们自己的窗口
API。通过运行在 rootless 模式,X 能够象这样被整合到一个宿主窗口系统中。在
rootless 模式下应用程序窗口绘制到系统内存中的缓冲区。在适当的时候 X
窗口和宿主窗口系统同步,于是它们的内容被显示出来了。Rootless X
也提供协议在两个环境当中传递鼠标和键盘事件。
X Render

现在讲到 X Render 扩展。Keith P 于公元 2000 年宣称现存的 X
服务器无法有效地绘制清晰的、反锯齿的文本,起而提出 X Render
扩展来解决此问题。X Render 是核心 X 特性,允许漂亮的字体和 Cairo
这类事情在 X 服务器上实现。X Render 给 X 服务器添加了 Porter-Duff
操作5。这些操作允许图面以不同的方式合并。它们与 OpenGL
纹理和纹理操作的概念非常相似,但仅仅是相似而非完全一致。
XAA

XAA,既 X 加速体系结构,是在 XFree86 4.0
中引入的。为达成跨平台可迁移性,XAA
没有利用内核设备驱动,而在用户空间实现了 2D
视频驱动。用户空间驱动的确可行,然而既然不存在基于内核的驱动,Linux
内核就无法追踪 X 对硬件作了些什么。直到你的系统引导完毕,X
都未开始运行。你应该希望启动过程中在启动 X
出麻烦的情况下仍有显示,不是吗?Linux
下的启动显示通过文本模式(控制台)驱动实现,最常见的是 VGAcon。由此 Linux
下你困于两套设备驱动, X
和控制台的,都在试图控制同一块硬件。XAA、控制台和虚拟终端(Virtual
Terminal)这类 Linux 内核功能的组合会导致大量的冲突,不过容后细谈。
EXA

EXA 对现存 2D XAA
驱动的替代允许当前的服务器模型能工作更长一点。它通过提供远为高级的驱动和内存管理
API 来加速 X Redner 扩展。起初 EXA
定位为针对包括旧硬件在内的所有硬件的方案。但这并未成为现实。如果老旧的硬件缺少加速渲染核心所需的
alpha 混合硬件,你基本上就无能为力了,虽然EXA
有可能通过较好地管理显存帮助增强这些芯片的性能。所以归根结底硬件 EXA
相当程度上工作于现存OpenGL 驱动同样的硬件。Nv 和 i128
这样的例外也是有的,这些硬件具有 3D 能力却不存在 OpenGL 驱动。可以确定的是
EXA 会不断扩张来探求更多芯片中的 3D 能力。EXA
牌创可贴能顶一阵子,但非长远之计。必须牢记的是 EXA/render 仍然仅是庞大的
Mesa OpenGL API 的子集,而随着时间的推移我们总会寻求越来越多的特性。
Cairo6

Cairo 的目标是成为一套高品质的、同时适用于打印输出和屏幕显示的 2D 绘制
API。它被特别着意设计得同 X Render 扩展协同工作,实现了 PDF 1.4
图像模型。有趣的操作包括笔划和三次 Bézier
样条曲线,转换与合成半透明图像,反锯齿文本渲染。Cairo
的设计是可移植的,且允许可挂接的绘制后端例如图像、glitz、png、ps、PDF、svg、quartz、GDI
和 xlib。目前 Cairo 已经过大约两年的开发,在 GDK 和 Mozilla
即将到来的版本中应该能看到部署。Cairo 的主要目标是使处理屏幕上的高端 2D
图形更容易,然后轻松打印它们。可挂接后端允许应用程序使用相同的代码绘制和打印。

Cairo 后端之一,名为 glitz,基于 OpenGL 实现了
Cairo。这里有一篇上佳的论文说明了glitz 的细节。既然 Cairo 同时实现了 xlib
和 OpenGL
后端,我们可以在两者间做一直接性能比较。在已发表的基准测试中,OpenGL
的速度在所有地方都以 10 到 100 比 1 的比率击溃了
XAA。这样巨大的性能差异正是由于 glitz/OpenGL
对图形芯片上3D硬件的运用。比较 glitz 和 xlib 上的 Cairo
是一个展现3D硬件具有在 2D 屏幕上绘制之完美能力的好方法。
DRI 与 OpenGL

DRI,直接渲染机构7,实现了与 X 服务器协作的 OpenGL。DRI
有四个主要组件。首先,libGL 提供 OpenGL
API,并作为在多个驱动间的切换器。其次,存在一套用于编程图形芯片的硬件相关的
DRI 库。对于DRI 驱动未能提供的 OpenGL
特性你需要一套软件后备实现。这个后备实现由 Mesa 提供。注意 Mesa
是一套完全的 OpenGL
软件实现。一块没有提供任何加速的卡仍然能够通过将每一个函数都交给 Mesa
来实现 OpenGL8。最后,就是 DRM,直接渲染管理器。DRM
驱动运行于内核,管理着硬件并提供必要的安全保护。

DRI 有意思的方面在于名字当中的 direct 代表的那部分。每个使用 DRI
的应用程序直接(directly)对视频硬件编程。这和 X
大异其趣,在那里你发送绘制命令给服务器,由服务器代表你对硬件编程。 DRM
内核驱动协调多个用户防止冲突。此模型的优点在于 OpenGL
绘制能够在无须进程切换及传输数据至主控服务器开销的情况下发生。一个缺点是图形卡必须处理大量图形上下文切换。工作站级卡一般能应对裕如,但部分消费级卡不行。Microsoft
已经撞上这个问题,并要求 DirectX 10 硬件提供高级硬件上下文切换支持。

DRM
还实现了比普通用户拥有更多能力的主控用户的概念。这些额外能力允许图形设备被初始化以及GPU
资源的消耗受到控制。当前的 X 服务器,以根权限运行着,作为 DRM
主控用户工作。实际上并无 DRM
主控用户运行在根权限下的真实要求,而且存在一个初步的补丁移除此要求。

一旦硬件缺少某种特性,Mesa
就以软件实现它。这称为软件后备。人们有时被这个绕住了。他们说他们的 OpenGL
没有被完全加速而X服务器一切正常。再想想看。两款驱动都运行在相同的硬件上。
OpenGL 未能完全加速,因为它提供了很多需要加速能力的特性,而 X
仅提供少量此类特性。如果你利用了同时存在于两款驱动 API
中的特性,他们可能都会被加速。如果没有,那就开始动手编程来修复对应的驱动。
安全性与根权限

Linux 内核包含了约 1000 万行以根权限运行的代码。X 服务器包含了 1600
万行代码,其中大多数运行在根权限下。如果搜寻安全漏洞,你认为最好下注在哪一处呢?其实并无技术理由要求
X 服务器以根权限运行。打着跨平台兼容性的旗号,当前的 X
服务器以根权限运行,以便从用户空间直接对视频硬件编程。 Linux
有个方案针对这种情况。你可以把特权代码放到设备驱动里,无须特权即可运行用户空间应用。一款一般的显示卡的特权设备驱动在
100KB 左右。那可是比 1600 万行少得多的代码需要审核。
怀旧版硬件

任何视频硬件,低档至 VGA 适配器,都可以运行 X 服务器,而且 Mesa
会非常乐意以软件实现整个 OpenGL
API。问题是有多快。并没有很多编程活动投注于将一块 VGA 卡变成 ATI
X850。这些旧硬件能被当前的 X
服务器很好地支持。但是新系统的设计正围绕新的硬件展开,并且它们很可能在旧硬件上表现差劲。你也许应该考虑一下升级你的视频硬件;具有适当
OpenGL 性能的全新图形卡能在 40$
的价位买到,二手价格甚至更低。作为替代,你也可选择不要升级,继续运行那些旧的对你已经够用的软件。
内核级图形支持

当内核开始引导,你面对的就是引导控制台。在 x86
平台上,最常见的引导控制台为 VGAcon。 VGAcon 使用你图形卡上的遗留硬件 VGA
支持。既然几乎所有 x86 图形卡都支持 VGA, VGAcon
为此平台提供了一个通用控制台。在非 x86 平台上你也许无法获得 VGA
硬件支持。在这类平台上你通常加载针对特定芯片的帧缓冲驱动。内核提供为数众多的
fbdev 驱动,由此范围相当广泛的硬件都被支持了。
VGA之余孽犹存

IBM PC 的原始设计定义了少数位于固定的、预知的地址的外部设备,例如 COM1 在
0x3F8。很不幸,大多数图形卡的 VGA
支持是这些位于固定地址的遗留设备之一。只要你的系统中仅存在一块图形卡,VGA
并不成问题。插入第二块,现在你有了两片都试图独占相同总线地址的硬件。

目前的 X 服务器包含处理多块 VGA 适配卡的代码。但是这些 X
服务器代码并不会感知到这些设备上的其他用户,而是会让他们乱作一团。搞乱这些程序并不好玩,所以我们需要某种方法来协调
VGA 设备的多个用户。Linux 上最佳方案就是向内核添加一套 VGA 仲裁机制。BenH
已经动手在搞一种 OLS 上讨论过的。

另一症结在于多块显卡的初始化。显卡具有 ROM,又称
VBIOS,在引导时执行以初始化硬件。出于历史原因,很多这类初始化用到了 VGA
支持。既然我们仅能有一块遗留 VGA 设备,系统 BIOS
转移了问题,仅初始化第一块显卡。在引导期间某个较迟的点初始化第二块卡也是可能的。这是通过以
vm86 模式运行第二个 VBIOS 并同等使用单个遗留 VGA
设备来达成。为了使问题更复杂,存在两种常见 ROM 格式即 x86 代码和 Open
Firmware。既然供应商对他们的 Open Firmware 型号收取高额费用,在非 x86
机器上使用 x86 视频硬件是很常见的。为了让这种做法可行,VBIOS 不得不使用
x86 仿真器来运行。BenH 也在为这个问题的一种方案工作。

Fbdev,又名帧缓冲。Linux
下,帧缓冲主要用途包括:初始化硬件,检测连接的显示设备,确定它们的有效模式,设定输出模式及配置,硬件光标,黑屏处理,色彩映射,取景和休眠/恢复。内核中存在大量帧缓冲驱动,它们实现了对这些特性程度不同的支持。请注意,尽管
fbdev 接口是基于内核的,并无障碍阻止存在实现于用户空间的辅助应用 fbdev
支持。辅助应用可用在缺少源代码的时候让 VBIOS 可用。

当你运行 VBIOS
时它建立一套非常低级的、用于控制显示的入口点。这事太细节化,我不准备解释
VGA、 Int10 和 VESA 之间的所有差异。作为概括, VGA 是 IBM
创立的基本硬件寄存器标准。 Int10
专注于用软件中断的方式处理显示输出。软件中断仅工作在 x86 实模式下,且除了
GRUB 之类很少被使用。支持 Int10 功能的代码来自 VBIOS,当 ROM
运行时被安装。仅允许存在一个被安装的 Int10 驱动。VESA 取代了 Int10
模式并扩展它到保护模式。配置内核时,有三个驱动: VGA 和 VESA fbdev,
fbconsole 也需要加载运行,VGAcon 则总是必要的。在非 x86 系统你通常需要
fbdev 和 fbconsole。
让多用户运转

Linux
乃多用户操作系统。且它一贯如此。但是连接多个用户的唯一途径就是通过串行线和网络。如果你安装多块显示卡并在本地跑多用户会怎样?此路不通。有一堆
Linux console project 这样的补丁和针对 X
的各种黑客行为试图让它运作起来。问题在于 Linux
控制台虚拟终端系统控制着本地显示卡且只能有效地支持单个用户。注意 fbdev
被多个用户使用的时候可胜任愉快,单用户的是 VT 系统。

多个本地用户在学校、监控系统、网吧甚至家里这样的地方都有应用。由于普通 PC
仅支持单 AGP 插槽,过去对多显卡支持的需求并不紧迫。多块 PCI
显卡可以工作,但性能不彰。也有带有多个 AGP 插槽的高端机器,但并不普及。PCI
Express 改变了这种状况。通过 PCI
Express,所有插槽从机理上是等同的。唯一不同的地方就是有多少通道连接到每个插槽。硬件上的变更让构建具有多个高性能显卡的系统变得轻而易举。计划中的
PCIe 支持芯片允许最多 16 块显卡共存于单一系统中。
分裂控制台

当分析控制台系统时,你会很快注意到有两种不同类型的控制台用法。系统控制台,提供引导显示并并勇于系统错误报告、恢复和维护。以及用户控制台,用户登录并处理命令行交互或编辑的普通显示。在目前
Linux 控制台系统中,两种用法都由同一套控制台代码处理。

按照用途分离控制台代码是可能的,能够修正很多 Linux
控制台当前存在的问题。一开始,系统控制台应当完全可靠且防篡改。它不必很快。它需要尽可能以最简代码实现而且它需要在系统中断和内核
panic 时保持运作。用处包括系统恢复及单用户模式。引导时显示和 kdbg
支持也是可能的。系统控制台会提供 SAK
和安全登录屏幕。为了支持无关用户登录到显示卡的每个头,它需要无关地在每个头上实现。一种访问新系统控制台的方式是通过
SysReq,控制台将覆盖你当前的显示并使用你当前的显示模式。Novell kernel
debugger 以这种方式工作。系统控制台不支持
VT,而且不存在控制台切换。既然它清楚你的显示模式,它能够在紧急情况下抢占你的显示,比如一次致命的
kernel OOPS9。

系统控制台的设计使用 fbdev
来追踪特定的模式及扫描缓冲位于何处。为了使它尽可能地可靠任何加速支持都被移除。
Fbconsole 则使用系统 CPU 直接处理帧缓冲。控制台通过利用 fbconsole
中现有位图字体支持直接绘制到输出缓冲来显示。

用户控制台是系统控制台的对立面,它需要是高性能和用户友好的。一个用户空间实现让它易于通过为每个用户创建一个进程来处理多用户。用户空间(实现)允许全速的通过
fbdev 和 DRM 的 GPU 加速。你还能轻易访问 Xft/FreeType 获得 Unicode
支持。借助适当的设计,控制台甚至允许分配不同的用户到不同的头上。通过适当编码的热键,它能够表现得和现存
VT 一样且支持控制台切换。

既然目前的控制台是合并在一起的,当你切换 VT
时你同时遇到这两种类型。新的模型中当前 VT
切换键会把用户空间控制台提供给你。 SysReq
则激活系统控制台。连接到系统控制台上的 shell
进程能运行于高优先级,让从一个失去控制的进程手里夺得控制权更轻易。
物以群分

本地多用户支持暗示着 Linux 会为用于 UI
的外设实现控制台组的概念。控制台组是发起 login console
所须硬件的集合。一个范例组包括显示器、鼠标、键盘和音频设备。登录时, PAM
将这些设备的所有权赋予登入的用户。对此概念的有趣附加是将 USB hub
或端口作为控制台组的一部分包括进来。一旦用户登入,任何接在 USB
端口上的设备也属于他们。登出时所有这些又返回到未分派设备池中。
候补的候补10

小把戏们: directfb、 svgalib、 fresco、 Y Windows、 FBUI,诸如此类。
Linux 吸引了一票想在显示代码方面一展身手的人们。在当前的 VT
模型下,这些另类显示系统在 VT 切换时导致了很多问题。切换 VT
之后,新近激活的显示系统被允许对硬件干任何它想干的事。那包括重新初始化它,重编程它以及清除它的
VRAM。当你切换回来,原始系统被指望能从更动后的硬件状态下恢复。不仅仅是这些小把戏们才在VT
切换中造成问题。你能在控制台和 X 甚至两套桌面比如 X 和 Xegl 中切换。对具有
14 个寄存器和32KB 显存的 VGA 适配卡这可能不错。但对拥有 300
个寄存器、512MB 显存和独立 GPU 协处理器的显示卡而言它不是一个良好的模型。
合作无间

我确信对此问题的最佳方案是由内核为每种显示硬件提供单独的、广泛的设备驱动。这意味着
fbdev 和 DRM
这类冲突的驱动必须并入一套可协作的系统。它还意味着一旦基于内核的设备驱动加载,从用户空间摆弄硬件的行为就应予禁止。我怀疑如果
Linux 为不同的显卡提供广泛的标准驱动,许多创建另一版本Radeon
驱动的冲动会冷却下来。

这并不表示 fresco
这样的项目不能开发他们自己的显示硬件设备驱动。只表示你不得不卸载标准驱动,然后在运行新程序之前加载你的定制驱动。这种卸载/加载行为和内核中的其它驱动并无不同。运用热键在针对同一块硬件的两个活动的显示设备驱动之间跳转(VT
切换)将不再被支持。如果基本的驱动缺乏需要的特性,较好的方案是向标准驱动提交补丁。通过在标准驱动中实现需要的扩展,所有程序能共享它们,通过用户空间控制台系统在使用它们的应用程序间切换也会很容易。

若我们继续保持提供热键在显示驱动间跳转的 VT
设计,我认为用热键在磁盘和网络驱动间跳转也被实现才是公平的。
OpenGL|ES

Khronos Group11 是一个由超过一百家成员企业发起成立的新进标准组织。Khronos
Group 最成功的标准是 OpenGL ES。OpenGL ES
针对内存紧张系统定义了一套非常有用的 OpenGL 子集。它还定义了
EGL,一套平台无关的 OpenGL GLX/agl/wgl API 等价物。"EGL
提供机制创建可供诸如 OpenGL ES 和 OpenVG 这样的客户端 API
在其上绘制的渲染图面,为客户端 API 创建图形上下文,并同步 Client API
的绘制行为,让它和原生平台渲染 API 一般无二。这允许无缝地同时运用 OpenGL
ES 和 OpenVG 做高性能的、加速的、混合 2D 和 3D 的渲染动作12。"

EGL 假设了由操作系统的其它部分提供的窗口系统的存在性。但是 EGL
的设计是平台无关的,不象 GLX/agl/wgl,EGL API
中没有什么是局限于某个窗口系统的。所有引用到本地窗口系统的地方都由屏蔽指针来处理。

Mesa 开发者已经合计出了一些提议来扩展 EGL,以便一套窗口化系统能够实现于
EGL 之上。该扩展的核心提供了一套 API
来列举可用的屏幕,设置屏幕的模式和帧缓冲配置,摇动屏幕,以及查询属性。两个领域,硬件光标和色彩映射,仍然需要
EGL 扩展加以解决。向 EGL 添加这些扩展提供了足够的硬件控制来实现一套 Xegl
这样的服务器和窗口化系统。OpenGL 加上 EGL 和 Mesa 扩展提供一套真正可移植的
API 来访问多种形式的图形硬件,范围从当前的蜂窝电话到 Playstation 3 到 PC
到图像超级计算机13。

扩展后的 EGL API 能够很好地和 Linux
匹配。它提供了一个坚实的基础来构造窗口化系统或嵌入式应用。易于使用,这使它成为研发和体验版的有趣平台。它令你集中精力到你的新应用或窗口系统,忘记所有那些和硬件打交道的复杂性。

我相信 Khronos Group 是 X.org 和 Linux
图形社区一个重要的未加利用的机遇。大多数 Khronos
标准缺乏开源参考实现、开发系统支持以及一致性测试。Khronos Group
后台中不少在销售给予 Linux 的产品系统。如果 X.org
扩大它的宪章,它能够作为一个中立的非盈利媒介在创建开源参考实现和开发基于
Linux 和 Khronos 标准的系统方面与 Khronos Group
进行接触。这种伙伴关系允许Khronos Group 成员对 X.org 作出慈善捐赠,正如
IBM 对 Eclipse 基金会所做的那样。
完美像素

完全精确到每一个像素其实是个神话。你唯一能提高的只是逼近精确的程度。误差的来源是多方面的。你
LCD
背光的均匀度,打印机墨水的一致性,数模转换的质量,纸张的反光度,颜色匹配问题,GPU
中绘制算法的不同实现,等等。OpenGL
并不保证不同实现之间的像素级精确性。要获得像素级完美性,最接近的方法是在你的每一个输出目标上使用完全相同版本的
Mesa 软件。顺便提一句,X
服务器也不是像素精确的。我的经验法则是如果差异需要用放大镜才能找到那就足够接近了。人们在这一点上往往没搞清楚。如果你丢给
OpenGL
一张位图供显示,它会原封不动地复制那些像素到屏幕上除非你让它改变它们。像素绘制精确性的讨论主要是针对直线这类可缩放的向量。

子像素反锯齿字体(Subpixel antialiased font14)并不是问题,OpenGL
提供了多种显示子像素反锯齿字体的方案。如果你选择那么做的话,OpenGL
也能使用和当前 X
字型显示严格相同的机制。既然机制相同,字型的表现也就相同。锁定到某个特定算法也令人不快,这么做会妨碍前进。例如,这篇论文(视频)探索了一种在
GPU
上生成字体的全新方法15。这里还有另一篇让人感兴趣的论文,"使用可编程图形硬件做解析度无关的曲线渲染,Loop
和 Blinn",发表于 SIGGRAPH
2005。如果字体绘制拘泥于像素级完美精度,也许就不可能应用这些新技术。这些字型由
GPU
生成,使用了硬件内建的算法,无法被用户调整。转换轮廓字型到像素然后作为混合的图像加以渲染只是显示字型的一条途径。可编程
GPU 则提供了新的替代手段。任何眼光长远的 API 都需要把这一点考虑在内。
三代同窗

在当前的 X 服务器和许多别的窗口化系统中,窗口是用 painter's algorithm
绘制到屏幕上的剪裁多边形里。 painter's algorithm
用和真实绘画一样的方式工作 –
每一个后来的层都覆盖前一层。你先绘制背景,然后以反向 Z
序绘制每个窗口。如果不存在透明并且你清楚所有窗口的来龙去脉,你可通过剪裁长方形优化此算法(正如
X
所做的),使屏幕中的每个像素仅绘制一次。性能还可通过追踪破损来提升。仅仅破损区域的窗口需要重绘,屏幕的其余部分被剪裁多边形保护起来。更进一步的收益可由"背景保存"获得。窗口化系统意识到部分组件如弹出菜单在失效时向屏幕上重绘相同的内容。"背景保存"保存了这些弹出窗口下的屏幕并在完成后替代它。

合成机制利用了近期硬件性能增进的优势。通过合成,窗口能够离屏绘制到不可见的那部分显存上。窗口管理器随即将窗口与屏幕的可见部分合成到一起。合成仍然使用
painter's
algorithm,不过既然窗口管理器总是拥有所有窗口内容,就有可能实现透明窗口。透明通过在复制到输出缓冲区时混合窗口在屏幕上的内容与前一个窗口的内容来实现。这称作
alpha 混合(alpha
blending)。大多数现代硬件支持它。绘制闪烁也通过双缓冲得以消除。在此模型下,一切仍然是
2D 并有简单的 Z 序。

高端多纹理硬件能够防止一味使用 painter's
algorithm。每个处于屏幕上关注区域的窗口将被视为独立的纹理。你绘制多边形到屏幕上以再现窗口。对每个窗口/纹理,这些多边形在顶点上都具有适当的纹理坐标,由此纹理合并器硬件会合并所有窗口/纹理并生成期望的结果。在极端情况下,整个屏幕通过渲染单个多纹理矩形来重绘!这项技术超快,既然闪烁最小化了,你可能甚至无须双缓冲。多纹理化的完整桌面可能还在今天的硬件的能力之外,但这是一个随着每一代硬件正快速提升的领域。

Xgl 实现了合成模型。虽然并非必须,Xgl 会运用一项新的 OpenGL
特性,帧缓冲对象 (framebuffer object)。通过 OpenGL 的一项扩展,FBO
允许窗口管理器治下离屏应用程序窗口的非常有效的共享。这项扩展并不那么困难,毕竟我们已经跨进程共享了
pbuffer。对于应用程序,FBO
看起来好象普通的可绘制窗口。对于窗口管理器,窗口看起来就象纹理,可以通过多纹理这样普通的绘制命令来操纵。在这个模型下,应用程序窗口仍然是
2D,但现在编写 Luminosity 这样基于 OpenGL 地窗口管理器成为可能。基于
OpenGL 的窗口管理器能使用 Z 缓冲合并窗口,并跳出严苛的 2D Z
序限制。例如,一个窗口能够变换成波状,并反复和另一个窗口相交。

最终你能够打破应用程序窗口的 2D 限制,赋予它们厚度或别的 3D
性状。比方说,弹出窗口其实可以弹出在较高的 3D
坐标处。当你将它与光源组合使用,自然形成的下拉阴影即可取 2D
下的人工构造而代之。绘制漂亮的阴影是复杂的,然而借助 OpenGL
的能力,任务变得容易许多。Sun 的项目 Looking Glass
就是这种类型的窗口管理器。在 Looking Glass 的 demo
视频中演示了窗口厚度。Looking Glass 使用一个 rootless 的 X
服务器运行现有的 X 应用。窗口由此具有了厚度,并和 CD changer demo 中的真
3D 应用共存。

3D 桌面的概念并不那么古怪。自从 Windows 1.0
的并列窗口前进到可覆盖窗口时我们已经拥有了3D 桌面—一旦 Z
序被引入,桌面即成为一非透视的 3D 空间16。看看菜单和弹出窗口,3D
概念遍及桌面。实现合成的一个主要理由在于提供下拉阴影,很明显是 3D
空间的一个 2D 再现。甚至按钮这样的控件也通过 2D 仿真被做得象
3D。何不把它们画成 3D 的,让用户控制光源呢?窗口透明显然包含着 3D
概念。我们何不干脆承认桌面是 3D 空间并使用 3D 图形来绘制它呢?
划清界限

这个主题存在一些争论。通往基于 GPU 的桌面的开源转换 Linux
真的只有一个选择- Mesa OpenGL 实现。自然我们能够克隆
DirectX,但谁来编写全部的代码和驱动? OpenGL
是个不坏的选择。无论我们构建什么,它都是 Linux
上必不可少的一项要求。它是标准化的,由 ARB (architecture review
board,体系结构评审委员会)所掌控。它设计精良,文档齐备。它的部署和应用广泛。大学教授有关它的课程,大量关于它的书籍已经写就。很酷的应用程序和游戏在它之上运行。

应该在何种层次上划分图形设备驱动的界线?XAA 和 fbdev
在低层次上划下界线。这些 API 把自己卷入到 framebuffer、bitblit
也许还有直线绘制的众多像素中去。在这一层次上图形芯片提供的任何特性不是根本不可访问就是需要芯片特定的
API 通过转码来访问。 Xgl 实现则以相当不同的方法来划这条线。界线被划在
OpenGL API 自身这样相当高的层次。我确信 Xgl
方案是较佳的选择。为了允许硅芯片在不破坏 API
的前提下演进,你期望以位于当前实现于硅芯片中的特性集之上的方式划分界限。我不相信
Linux 会从 DirectX 那样运行一堆 API
中受益。较好的模型是从真正高的层次出发,提供参考软件实现,即
Mesa,然后用加速的硬件实现,即 DRI,分片替代 Mesa。我们也拥有多个 OpenGL
实现:Mesa、nVidia 和
ATI。使用哪一个取决于你的选择,信不信由你有些人竟喜欢专有驱动。

Xgl 被设计为一项短期过渡方案。Xgl 的模型是用一套基于 OpenGL
作为设备驱动的兼容系统透明地取代现存 X 服务器的绘制系统。Xgl 将全部现存 X
API 作为主要 API 来维护。没有任何新 X API 被引入,也没有任何被废弃。Xgl
是一套高层次的、跨平台的代码库。它是一般化的代码,需要被移植到特定的
OpenGL 环境中。一项移植, Xglx,立足于 GLX API 上。另一项移植,
Xegl,工作在跨平台的 EGL API 上。注意 EGL 是一种表现 GLX、agl 和 wgl API
的平台无关的方法。通过 Mesa 扩展 EGL
能控制低层帧缓冲。该组合提供了在裸显示硬件上实现窗口化系统(类似目前的 X
服务器)所需的一切。然而 XGL是一项短期过渡设计,通过推迟对 XGL 的需求,EXA
牌创可贴很大程度上缓解了对它的需要。

一个被反复提及的争议是,因为所有那些在这个不断发展的世界上仍在使用的老旧硬件,我们不应当使用
OpenGL。对这个问题有两个解。其一,OpenGL 是一套可伸缩的
API。借助软件后备实现它能运行在最低档的硬件上。 OpenGL ES 也提供 API
profile。 Profile 是定义良好的 OpenGL API
子集。如果有必要我们能够定义一套包含可能的最小 OpenGL API 子集的最简
profile。代码尺寸应当不成问题,一个专有的 100KB OpenGL ES
实现已经可用。另一套 OpenGL ES profile
则不要求浮点支持。没有什么能够妨碍开源的对应软件的构建,如果我们选择投入资源的话。

另一个分歧是简单地在软件被设计来使用的硬件上运行它们。没人期望一台原始的
IBM PC 运行 Windows Longhorn,但是同一台 PC 可以毫无问题地继续运行 DOS。

这里的关键之处在于 OpenGL 比 EXA 更具伸缩性。在高端 EXA
的伸缩性不堪一用,它并未包含 3D 和可编程性这样的高级 GPU 特性。透过
OpenGL,就有可能对从蜂窝电话到超级计算机的所有情况都拥有单一 API。
九层之台

你有一堆缩写需要消化。感觉一下这些库是如何协同工作的例子:

App -> gtk+ -> X -> XAA -> hw

这就是当前的 X 服务器。应用程序和 toolkit 对话,toolkit 使用 xlib API 调用
X 服务器。X 服务器利用当前的 XAA 驱动绘制到硬件上。X
和应用程序位于两个不同的进程中。

App -> gtk+ -> Cairo -> X Render -> X -> XAA/EXA -> hw

Toolkit 使用新的 Cairo 库。Cairo 的行为则取决于 X Render。如果 EXA 可用,X
Render 被加速。X 和应用程序位于两个不同的进程中。

App -> qt -> Arthur -> X Render -> X -> XAA/EXA -> hw

Arthur 是 Trolltech 的 Cairo 等价物,很大程度上两者的作用是相同的。

App -> gtk+ -> Cairo -> glitz -> GL -> hw

Toolkit 使用新的 Cairo 库。Cairo 选择 glitz 后端来获得基于 OpenGL
直接渲染。一切都是加速的,鉴于 OpenGL 是直接渲染的,绘制发生在单个进程内。

App -> gtk+ -> Cairo -> X Render -> Xgl -> EGL(standalone) -> GL -> hw

这种情况下,toolkit 为 Cairo 选择 xlib 后端,从而和邻接 X Render 的 Xegl
服务器对话。Xegl 使用 Xegl 提供渲染实现。Glitz 则直接渲染到硬件。Xegl
和应用程序位于两个不同的进程中。注意 toolkit 能够选择直接使用 glitz
并在单个进程内直接渲染。

App -> gtk+ -> Cairo -> X Render -> Xgl -> GLX(X) -> GL -> hw

再一次地,Toolkit 通过 X render 和 Xglx 服务器对话。Xglx
并非独立的服务器,它是一个嵌套服务器。Xglx
也非一个普通的嵌套服务器,它利用嵌套获得输入,但在由父服务器提供的单个
OpenGL窗口内绘制自身的整个桌面。一旦进入全屏,你不再见到父服务器。存在三个进程,应用程序、Xglx
和 X 服务器。绘制在应用程序和 Xglx 之间发生,因为 Xglx
使用直接渲染。既然第三个进程,即 X
服务器,提供窗口和输入服务,它也是重任在肩。它还是 Xglx 程序的宿主。
前路17

Linux 目前成为最迟实现充分利用 GPU 优势的桌面 GUI
的主要桌面。鉴于这个既成事实,不再有任何时间压力,也许应该考虑一项长远的方案。我们能够围绕
OpenGL 和 Cairo 设计一个新的服务器。

一般而言,整个可编程图形硬件的概念并未在 xlib 和 Cairo 这样的 API
当中触及。这是非常重要的一点。一项主要的 GPU
新特性,即可编程性,简单地无法从当前的 X API 中访问。 OpenGL 通过它的
shader 语言提供这种可编程性。

当考虑新服务器的时候,理所当然将概念设计分解为两个组件:平台相关与平台无关。设备驱动属于平台相关部分,拟议中的模型里
OpenGL 被看作设备驱动,所以会有平台相关的实现。所有同其它 Linux
子系统整合的细节问题都会隐藏在特定的驱动之后。主服务器将使用跨平台
API,诸如 sockets、OpenGL 和 EGL,来实现。一套用于热拔插设备的跨平台 API
也需要规范。此服务器无须从头设计,其实质部分能够重用来自其它项目的代码,只是要合并到新路子上来。依我之见,构建一个新服务器所需代码的百分之九十五甚至更多已经有了。

模块化是构建优秀服务器的关键之处。设计应当分解为通过标准化接口沟通的独立库。这样分解让替代某个库变得容易。你可以在不同的平台上采用不同的库实现,或者在单个平台上以不同的方式实现库。自然,跨平台代码有它的优点。Mesa
库这类材料能在所有目标系统上共享。

还记得 DirectFB 是如何使用 rootless X 的吗?新服务器将通过运行软件渲染的
rootless X 来保持与遗留系统的兼容。 DRI
的直接渲染模型是良好的设计,在未来的服务器上应予保留。将 X
转为遗留状态允许在设计新服务器时获得完全的自由。

比方说,新服务器能够设计一个全新的网络协议。最近 Linux Journal 上关于 No
Machine 和 NX 协议的文章表明 X 协议能够被压缩至 200:1
甚至更多。新协议将是基于 OpenGL
的,并被设计来防止双程延迟以及提供持久图像缓存。 Chromium
是一套有吸引力的系统,支持将 OpenGL
显示分解到通过网络连接的多个显示器上。他们的网络库处理 OpenGL
状态追踪,作为防止网络流量的一种手段。

字型缓存也应当加以分析。在目前的 X
服务器中,客户端生成字型位图,然后将它们发送到服务器,在那里它们被缓存起来。这个模型排除了早先引用的论文中讨论的利用
GPU
生成字型的方法。客户端字体是好的想法。应用程序理所当然应当负责布局。但是并无实际的要求由客户端生成字型位图。

新服务器能够解决当前在网络音频和打印方面的不足。它能够支持重连会话所需要的适当的代理行为。它也应当明确地从一开始就设计为支持多用户。

事件处理是用库构建系统的良好范例。 Linux 有 evdev、kernel hotplug、HAL 和
D-BUS。这些子系统在大多数其它平台上并不存在。因此,为 BSD
设计的输入子系统看起来会和为 Linux
设计的相当不同。将主要的子系统模块化让它们能够被定制和充分利用它们运行的平台环境。比起针对不同环境的最小公分母来设计,这是一种不同的途径。

X 为世界各地的众多情报机构使用。当前的 X
服务器被认为还没有足够安全到可用于处理敏感文档。如果主要的设计工作开始进行,它能够从根基上就特别留意安全性。适当的投入会持续以确保正确的特性被实现。

长话短说,有很多工作需要完成,最近的开发已经开始解决这些问题。第一位的是
DRM 的内存管理器和打开 DRI 驱动中
FBO(帧缓冲对象)所需要的改写。第二位的是清理现有 fbdev
驱动,使它能与已有DRM
驱动的硬件协调工作。随着奠基工作的就绪,全新服务器的设计工作就可以着手进行了。
结语

我从 Xegl
的失败获得的经验告诉我,构建一个图形子系统是一项大而复杂的工作,其规模远超过一两个人所能承担的。作为一个整体,X.org
社区仅仅具有足够的资源创建单个服务器。将这些资源分配到不同的方向上只会导致一堆半途而废的项目。我理解开发者比较愿意为那些引起他们兴趣的东西工作,但是鉴于
X.org
拥有的资源,这种做法不会在近期孕育出新的服务器甚或基于旧服务器然而富有竞争力的桌面。也许
X.org 是时候释出一份路线图供所有人追随了18。

Jon Smirl

于 2005 年 8 月 30 日

授权可自由地翻译和再发布19。

0 以下的注解都是译者另加,主要目的是提供一点背景和 Linux
图形方面的进展供读者参考。首份译文完成于 2006 年 7 月 7 日,是 gogoliu
发起的《Modern X Tech. 中文翻译计划 》项目的一部分,这是 2006 年 8 月 4
日修正版,都是极细微的修正,读过的可略过。另外我花了点时间看了下 html 和
xhtml,现在的 html 和 xhtml 格式都是我手工编写的了,效果应该比
OpenOffice.org 2 生成的为佳,尺寸也小些。对译文的指教,可联络 mopz0506
[AT] gmail [DOT] com,标题请务必包含"The State of Linux Graphics"
字样。永远怀念在八年抗日战争中牺牲的国共两党将士们。

1 原文(http://jonsmirl.googlepages.com/graphics.html)发布于 2005 年 8 月
30 日,所以基本上是一年前的现状。

2 但是随着 Internet 的增大,对人们获取知识和真相的恐惧也增大了。

3 和 Jon Smirl 不同,其实 K.P. 作为 XFree86 的叛逆者,对一切 3D
化的倾向,反应并不是很积极的。 K.P. 说过,95% 的时间都是在跑
2D。译者就无所谓了,反正 95% 的时间都在跑控制台和 ncursor :)

4 X11R7.0 已于 2005 年 12 月 21 日由 X.Org 正式发布。 X11R7.1 已于 2006 年
5 月 22 日由 X.Org 正式发布。这是第一个享受模块化带来的益处的 roll-up
发布。

5 Porter-Duff 操作是 1 组 12 项用于描述数字图像合成的基本手法,包括
Clear、Source Only、Destination Only、Source Over、Source In、Source
Out、Source Atop、Destination Over、Destination In、Destination
Out、Destination Atop、XOR。通过组合使用 Porter-Duff 操作,可完成任意 2D
图像的合成。这里有 Thomas Porter 和 Tom Duff 发表于 1984
年原始论文的扫描版本 http://keithp.com/~keithp/porterduff/p253-porter.pdf

6 Cairo 1.2 已于 2006 年 7 月 1 日正式发布。另外,最近 Cairo 项目在 google
上搜索 Cairo 关键词时的排名已超过埃及城市 Cairo,稳居第一。

7
机构这个词很少在计算机方面的文章中出现。其实机构是一个很有内涵的词,也是机械方面的一种专门学问。我不喜欢架构这个词,因为架字让我感到隐含有草率的意味。我更喜欢体系结构这个说法。其实国内大概最早关于
architecture 的一本书(98年?99年?),《Software Architecture: Perspectives
on an Emerging Discipline》
影印版,印象中书名就是译成《软件体系结构》的。可惜不小心遗失了。

8 Mesa 就是作者忘了说的那个"再次"。

9 kernel OOPS 中的 OOPS 并不是某个缩写,来自英语中常说的
Oops,相当于汉语中哎呀呀,坏乐这类意思,随着时间逐步演进为特定场景下的专有名词。内核源代码的
Documents 目录下有一篇 oops-tracking.txt 文档。《Linux Kernel
Development》第18章 Debugging 有一节专门介绍 oops 的,可参考。

10 这让我回想起很久以前读过的一本描述 DEC 公司一群年轻工程师设计 PDP
小型机的故事的书,当中有个非常好的比喻,说某个改进方案是瘤子上又长瘤子。书名大概是《The
soul of a new machine》。

11 根据 opengl.org 在 The OpenGL Pipeline Newsletter
第一期(估计也是最后一期)中的官方说法,OpenGL ARB 将并入 Khronos
组织,OpenGL 也将随之和 OpenGL ES
成为同门,甚至再次融合也不是没有可能的。让我们期待此举为沉寂已久的 OpenGL
带来更多活力。

12 这段引文是来自 http://www.khronos.org/ 描述 EGL 的一段话。

13 graphics supercomputers 一般指比较强的可视化工作站,SGI 那种类型的。

14 LCD 上 RGB
三色其实是靠得很近的三个点,所谓子像素反锯齿字体就是利用这个特性增强 LCD
显示效果的一种手段。

15 论文中述及的方法已经在XGL中实现了。

16 这是说,此3D空间的对象并不具备透视关系,比如距离近点看起来大点什么的。

17 在那崎岖崎岖里看阳光......

18 很想译为:噫!树一帜而天下影从,此其时也!

19
译完了,似乎懂了一些,其实没有懂。一篇文章想要译得神完气足,实在需要不菲的心力。以我的理解,作者对
Linux
图形的现状显然是失望的,我无法译出这种味道来。感到非常对不起作者,可是没办法。

原文地址 http://mxtctp.googlepages.com/GraphicsCN.html

Linux的X窗口系统结构说明

一、说明
以X Server为中心,简要地分为四层,如图所示


二、X方式与Framebuffer方式的差异

1. X方式

1) 什么是X
我们常说的X Window,X,X11(指X协议的11版本)一般指X协议,或指是基于X协议的X服务端程序(X Server)

2) X Server与X Client

a) X协议指X Server及X Client组成的c/s架构,及其通讯协议的实现

b) X Server有主事件循环,由它来处理用户输入、显示及与X Client通讯

c) X Client即X桌面上运行的普通应用程序
应用程序如果想显示数据,需要利用X Lib库建立X窗口(X Client),它通过X协议与X Server通讯,让X Server完成显示;X Server会把接到键盘鼠标事件,传给焦点所在的X Client处理

2. Framebuffer方式
Framebuffer方式相对简单,它由内核直接支持,通常用于嵌入式系统。应用程序可以得到屏幕显示区域的指针,然后对其写数据来进行显示,其中窗口的概念不强,它自身不带窗口管理,需要应用软件自己管理窗口。比如qtopia基本于framebuffer显示时,qtopia自身实现了窗口管理功能

3. 应用程序的显示方式
很多应用程序同时支持X和Framebuffer两种模式显示,如gtk,qt等,以下我们只讨论它基本于X实现的部分

三、分层

1. 应用层(Application)
指X Window上运行所有带图形界面的应用程序,每个窗口都是一个X Client

1) X Lib app
直接使用X函数的应用程序,这种程序一般界面简单,比较底层,比如很多窗口管理器直接写在这层

2) Gtk app
gtk又分为gtk和gdk两层,
gtk为控件及主循环的实现
gdk相对底层,控制底层绘图部分,它支持framebuffer、X11、DirectFb等
应用程序可调用gtk函数,也可直接调用gdk函数
gtk常和cairo一起实现二维特效

3) Qt app
Qt也通过调用X Lib实现图形界面
Qt的优势在于它是C++实现的,使用起来程序结构更好,也有较成熟的嵌入式版本

4) SDL app
SDL也通过调用X Lib实现图形界面
SDL更底层,代码少,没有控件,但做特殊效果很好用

2. 窗口管理器层(Window manager简称wm)
Window manager是特殊的X Client,也通过X Lib库与X Server交互,与一般应用不同的是:它负责控制各个窗口的动作,及操作主窗口
WM的功能分为管理(manager)和工具(tools),

1) Manager
负责各个窗口的建立销毁/显示隐藏/最大最小化/移动缩放,管理窗口队列,设置焦点窗口,窗口切换效果等

2) Tools
实现桌面工具条,桌面菜单等基本界面及小工具

3) 具体实现
实现通常有两种方式:一种是manager和tools在一个程序中实现,一种是分开两个程序实现,使用时可以随意组合

a) qvwm, blackbox等较早期的wm,都是manager和tools在一个程序中实现的

b)
xfce、metacity等是分开的,例如:xfce包含tools和manager,但不在一个程序中实现,它的manager是xfwm,我们可在使用xfce时把xfwm替成metacity(metacity是一个manager,不带tools)

3. X服务器层(X Server)
主循环控制显示,读取设备数据,与X Client通讯,事件循环,并把事件送给焦点窗口

1) 普通X Server
功能完整的X Server,代码量大,支持全,常见的如XFree86,Xorg等

2) Tiny X Server
一般用于嵌入式系统,资源占用小,代码少,功能及逻辑相对简单,如KDrive(Xvesa/Xchips/Xfbdev/Xi810……)

4. 系统底层(System)

1) Kernel
与硬件交互,获得输入设备的数据,向显示设备输出

2) Dev
文件系统中的设备文件,程序通过对它的读写和操作与kernel交互,控制硬件

3) 中间层
在程序和Dev层之间,有时还需要库或程序处理设备数据,比如触摸屏就使用libts去除噪点,过滤出更有效的数据

Linux 服务的介绍

服务列表(按字母顺序排列)


服务名 必需(是/否) 用途描述

acon 否 语言支持
acpi 否 电源管理
acpid 否 监听精灵进程
adsl 否 内部ADSL开关控制
alsa 否 高级Linux声音构件
anacron 否 周期命令调度程序
apmd 否 电源管理
apmiser 否 电源管理
arpwatch 否 以太网IP地址配对监控器
atd 否 周期命令调度程序
autofs 否 自动安装服务
bluetooth 否 蓝牙技术核心
bootparamd 否 导入服务
canna 否 日语转换引擎
capi4linux 否 基本CAPI子系统
cpqarrayd 否 硬件服务
cpufreq 否 硬件服务
cpufreqd 否 硬件服务
crond 是 周期命令调度程序
Cups-lpd 否 使旧式Lunux或商业Unix系统连接到打印主机上.
cups 是 公共Unix打印系统
cvs 否 并发版本系统
devfsd 否 系统维护
dhcpd 否 DHCP服务器
diald 否 拨号网络智能自动拨号器
dkms 否 DKMS自安装导入
dm 是 显示管理器
dnbc 否 数字网络绑定Chrooter
Drakxtools-http 否 小型服务管理服务器
dund 否 蓝牙拨号网络
fam 否 文件系统变更监控器
finger 否 数据远程访问
freshclam 是 ClamAV更新器
gpm 是 鼠标
haldaemon 否 硬件监控系统
harddrake 否 硬件服务
heartbeat 否 高可用性服务
hidd 否 蓝牙H.I.D.服务器
hplip 否 惠普Linux打印与成像
hpoj 否 Pital?init,惠普办公喷墨打印机驱动器
httpd 否 Apache网络服务器
hylafax?server 否 企业传真机?调制调解器服务
ibod 否 按需ISDN MPPP带宽
identd 否 TCP连接鉴定
imaps 否 安全IMAP服务器
imaps 否 IMAP服务器
iplog 否 用主机名或远程主机记录TCP,UDP,ICMP.
ipop2 否 POP2邮件服务器
ipop3 否 POP3邮件服务器
ipsec 否 加密与验证通信
iptables 是 基于Packet过滤防火墙内核
ipvsadmin 否 Linux核心IP虚拟服务器
irda 否 红外线设备界面
keytable 是 键盘映射
kheader 否 导入服务
lads 否 登录异常探测系统
laptop mode 否 电源管理
leafnode 否 X? INETD NNTP服务
lisa 否 局域网信息服务器
lmsensors 否 硬件健康监控器
mailman 否 GUN邮件列表管理器
mandi 否 交互式防火墙
mdadm 否 软阵列监控服务
mdnsresponder 否 零配置DNS配置工具
messagebus 是 事件监控服务
mon 是 系统监控精灵进程
mysqld 否 MySQL服务器
named 否 绑定(BIND)服务器
netplugd 否 网卡精灵进程
network 是 网络
nfs 否 网络文件共享
nfsfs 否 网络文件共享服务器
nfslock 否 NFS文件锁定
nifd 否 Howl 客户端
nscd 否 密码与群查找服务
ntpd 否 NTP服务器的第4版
numlock 否 数字锁定键灯光控制
Oki4daemon 否 OKI4和兼容win打印机的兼容性精灵进程
pand 否 蓝牙个人区域网络
partmon 是 分区监控
pcmcia 否 个人电脑内存卡国际协会
pg_autovacum 否 PostgreSQL维护
pop3s 否 安全POP3服务
portmap 否 RPC支持
postgresql 否 Postgresql数据库引擎
postfix 否 电子邮件服务器
pptp 否 PPP断电服务
prelude 否 IDS
psacct 否 进程计算
rawdevices 是 分配raw设备,阻止其使用
rsync 否 远程同步
saned 否 网络扫描仪
shorwall 是 防火墙
smartd 否 自我监控服务
smb 否 Samba网络服务
snmpd 否 简单的网络管理协议
sound 否 声音系统
squid 否 高速缓存工具
ssh?xinetd 否 X?inetd OpenSSH服务器
sshd 否 OpenSSH服务器
subversion 否 并发版本系统
swat 否 Samba网络管理工具
syslog 是 系统登录
tmdns 否 多点传送DNS响应器
ultrabayed 否 ThinkPad工具
upsd 否 NUT精灵进程及驱动器
upsmon 否 UPS监控工具
vncserver 否 虚拟网络计算服务器
Webmin 否 远程管理工具
winbind 否 Samba名称服务器
wine 否 Wine并非竞争者
wlan 否 控制精灵进程
x?inetd 是 监控并控制其它服务器的服务器
xfs 是 X字体服务器
ypbind 否 SUN的YP服务器名称服务器

新“诗词填句”

年轻的女老师,在批改学生们的试卷时,被雷翻了!

1."床前明月光",下一句同学填"李白睡的香"…
2."三个臭皮匠"下一句他竟然填"臭味都一样"…批卷老师立即昏倒…
3.陶渊明的"不为五斗米折腰",那同学斗胆的写"给我六斗就可以"…
4."穷则独善其身",下一句同学填"富则妻妾成群"。
5."西塞山前白鹭飞",下一句"东村河边乌龟爬"?
6."天若有情天亦老",下一句"人若有情死的早"?
7."葡萄美酒夜光杯",下一句"金钱美女一大堆"…
8."想当年,金戈铁马",下一句"看今朝,死缠烂打"…
9.这个才过瘾!"洛阳亲友如相问",同学对"请你不要告诉他"…
10."两情若是长久时",同学对"该是两人结婚时"
11."书到用时方恨少",同学对"钱到月底不够花"…
12."清水出芙蓉",有人写"乱世出英雄"…
13."问君能有几多愁",同学填"恰似一壶二锅头"。
14.这个绝了!"日照香炉生紫烟,李白来到洗手间,小李飞刀一瞬间,李白变成小太监"…