2009年5月31日星期日

论嵌入式Linux下窗口系统的性能

在当前嵌入式Linux环境下,其体系架构以ARM为主,这里的分析也将以ARM芯片为主。
在ARM体系架构中,GPU自身是没有显存的,其是将系统的内存一块预留出来分给GPU,这样CPU、GPU、LCD通过AHB总线与内存相连。
这样LCD周期性的从显存中获取数据,占据了总线的带宽。其对性能的影响,另外一篇文章有讲述。
为了无闪烁的显示一幅图,我们往往是先在内存中画好这幅图,然后将其拷贝到拷贝显存中,这就涉及到一屏内存的写,一屏内存的读,一屏内存的写,对系统的内存占用极大。
当设备的分辨率增大时,每屏的数据量也急剧增大,总线必将成为性能的瓶颈。

下面将嵌入式设备与PC的架构进行对比
1、当前嵌入式设备中,其总线的宽度为32位,而在PC设备中,其总线的宽度为64位。
2、嵌入式设备中,一般选用SDRAM,目前也有使用DDR的,总线频率一般较低133Mhz,而在PC中,DDR、DDR2内存已经得到广泛的使用,其内存总线的频率更是高许多。
3、嵌入式设备中,CPU上的cache一般较小,而PC中的cache要大许多。
4、LCD周期性刷新要占用内存总线,而在PC中,如果采用内置显卡,则LCD刷新占用内存总线,如果采用独立显卡,则LCD刷新不占用内存总线。
5、嵌入式设备屏幕分辨率一般较小,这是其有利的地方。PC的分辨率一般较大。

从这方面考虑,当前ARM芯片的cortex-a8已经达到了1Ghz,应该说主频不是问题,其架构决定在支持高分辨率的设备时,其总线将成为瓶颈。
可以在软件上采取一定的方法,减少内存总线的占用。
1、在图形系统使用双buffer机制,这样我们在生成一屏的时候不必写到内存,然后再拷贝到显存。直接写到显存就可以了。
2、降低LCD的刷新频率。
3、使用thumb指令,提高代码密度,减少代码占用总线的时间。
4、在写内存时,最好一次写满32位,充分利用总线的宽度。
5、尽可能的使用寄存器,少用内存。用计算密集型取代大内存。

Linux的桌面系统个人感觉一直很低效。尤其是针对嵌入式的窗口系统,QT/E有些大,但成熟一些,不过商用要花钱。DirectFB在支持多进程时会有问题,GTK+Xwindow虽然免费,但其效率低下。
在Window下,其窗口系统都内置到操作系统中,这样进程显示位图,或者取得窗口位置等只是系统调用就可以了。而在Xwindow下,则属于进程间通讯,频繁的画图操作必然导致频繁的进程间切换,而导致系统的低效。
Linux一直引以为自豪的是,如果图形系统瘫掉,kernel依然正常,它也是一直拿这点嘲笑windows。可是对于嵌入式Linux设备,对于用户来讲如果图形系统瘫掉,kernel正常是无任何意义的。因此将Linux下一些窗口系统以模块的形式加载到kernel中是可行的。

现在还有一个问题,严重制约系统性能。
比如说画线来讲,如果我想利用GPU的硬加速功能,其必要要求所画的区域必须在显存中,GPU是不认识虚拟内存的,这样图形系统就在CPU和GPU之间割裂开来。
如果我们在使用窗口系统时,直接在显存中申请内存,则可以利用GPU的硬加速功能,但那嵌入式设备必然要为图形系统预留很多的内存,这部分内存就不能为应用程序所使用,必然会造成资源的浪费。
结果目前虽然GPU空有很多本领,但在大部分窗口系统中并没有得到应用。

导致这种现象的根本原因在于GPU不认识虚存,CPU中是有专门的内存管理,而GPU没有。但目前嵌入式设备中,CPU越来越多的集成了GPU的功能,那么让GPU认识虚存也不见得是不可能的事情。那时窗口系统利用GPU的硬件加速功能将更为容易,当GPU并行的对显存处理时,内存总线将会成为瓶颈。

没有评论: