Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3150096
  • 博文数量: 117
  • 博客积分: 10003
  • 博客等级: 上将
  • 技术积分: 5405
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-23 09:34
文章分类

全部博文(117)

文章存档

2011年(1)

2010年(10)

2009年(69)

2008年(37)

分类: LINUX

2009-04-30 20:34:56

在嵌入式平台Linux,主要通过framebuffer来显示UIFrameBuffer实际上就是嵌入式系统中专门为GPU所保留的一块连续的物理内存,LED通过专门的总线从framebuffer读取数据,显示到屏幕上。

根据系统中framebuffer的数量,可以分成单buffer和双buffer两种。

       先来说说单buffer

       CPUframebuffer上写,LEDframebuffer读,这是两个同时进行的过程,需要在时间上配合,否则会出现问题。

       如果CPUframebuffer上写的速度>LEDframebuffer读的速度,那么就有可能出现LED在一行一行的读取前一屏数据的时候,CPU却已经刷新了整屏,从而导致显示混乱。这里要注意,LEDframebuffer读的速度并不等于屏幕的刷新频率,如果刷新频率为60hz,那么很有可能LED花了3ms去读,剩余的时间都在等待。应该说CPUframebuffer写的速度>LEDframebuffer读的速度还是很困难的。

       如果CPUframebuffer写的速度太慢,也会出现屏幕闪烁的问题。比如说要画一幅图,CPU首先将其填充为白色,这时LED刷新,屏幕显示为白色,之后开始画完其他内容,屏幕正常显示。这时给用户的感觉就是屏幕一闪。这就要求CPU尽快的画完一屏,尽量保证写一屏不要跨越LED刷新周期。

       因此,在单framebuffer的时代,为了防止屏幕出现闪烁,我们一般是在内存中开辟一块与framebuffer同样大小的内容,将屏幕的内容都写好,然后再执行一次内存拷贝。从而使写framebuffer的时间尽可能的短。

       但这种机制有问题,我以屏幕分辩率为320*240为例。

       一块framebuffer的大小为:320*240*4=0.3072M

       也就是说,我要先在内存中填写0.3M的内存,然后再把这块内存拷贝到framebuffer中。为了简单起见,这里我举一个将屏幕置为白色的例子,排除屏幕内容计算的影响。

       显示的实际过程为,将内存中0.3M置为0,然后读取这0.3M的内存,拷贝到Framebuffer中。

       在我使用的嵌入式平台中,采用的是SDRAM532MhzARM11芯片。通过使用lmbench得到内存访问的速率为:

*Local* Communication bandwidths in MB/s - bigger is better

-----------------------------------------------------------

Host           OS  Pipe AF    TCP  File     Mmap  Bcopy  Bcopy  Mem   Mem

                          UNIX      reread   reread (libc) (hand) read write

--------- ------------- ---- ---- ---- ------ ------ -------- ---- -----

phone  Linux 2.6 79.1 94.7 13.3  47.1    135.9   78.6   77.8  135. 205.9

很奇怪,为什么读会比写慢,可能与cache有关,这里先不用去管它。

下面我来计算单buffer所使用的时间。

       0.3M内存置为00.3072×1000/200=1.5ms

       0.3M内存:0.3072×1000/135=2.7ms

       03M内存写到framebuffer00.3072×1000/200=1.5ms

总共时间为5.7ms。实际的传输情况要比这个多,因为还要涉及循环的开销。

5.7ms看起来还行。

当屏幕分辨率变大时,情况就不一样了。如果屏幕的分辨率扩大为800*600,那么其数据量将是320*2406.25倍。那么单纯的显示一个白屏的时间,将为5.7*6.25=36.6ms,也就是说如果只是显示白屏的话,我们也最多显示30帧,这个时间实在是太长了。

       并且如果我们只计算从内存拷贝到framebuffer的时间,其为 2.7+1.5*6.25=25.25ms。如何LED刷新频率为60hz,那么刷新一屏的时间将为18ms,这样即使单纯的从内存拷贝到framebuffer,写一屏的时间也大于LED的刷新频率,肯定会造成屏幕的闪烁。

       buffer的另外一个问题在于,其每次都要进行内存拷贝,这样其会重新刷新CPU中的数据cache,对软件的性能有不利的影响。

 

性能的改善:

       从软件的角度来讲,每次尽量缩小刷新的区域,减少内存的传输。

       从硬件角度来讲,采用更高的CPU,采用更快的DDR内存,提高内存的吞吐率。

      

下面再来说下双buffer

buffer的好处在于,在LED显示当前framebuffer时,软件可以直接向后台的framebuffer写,在写完之后只是两个buffer做下切换即可,不再需要内存拷贝,从而提高效率。

还是以显示一个320×240的白屏为例,其过程变成:

1、  直接向后面的framebuffer写,其花费时间为0.3072×1000/200=1.5ms

2、  写完之后framebffer切换,这个时间可以忽略不计。

那么当屏幕变为800×600时,其所花费的时间为1.5*6.25=9.375,要比单buffer的效率提高2.6倍。

并且双buffer还有一个好处,由于其没有了内存拷贝的环节,其对数据cache的影响较小,对于提高软件性能有利。另外给framebuffer的数据置位,其必然要经过Cache,由于这些数据写完后不再使用,那么使用写透cache要比使用回写式cache效率高。

 

buffer还有一个好处,就是可以利用GPU的硬加速。如果要利用GPU的硬加速,则显示的数据必须是在预留的物理内存中,这在单buffer机制中是不能实现的。

 

buffer也有一个致命的弱点:那就是局部刷新。

在单buffer的情况下,很容易实现局部刷新,只需要把局部的数据拷贝到对应的位置就可以了。而双buffer来讲,如果要实现局部刷新,则必须先将当前显示的buffer数据拷贝到后面的buffer,然后再做局部刷新。这样对于双buffer的设备来讲,刷新整屏的效率要比局部刷新更高。

 

局部刷新的理想情况:

将局部要修改的数据,直接写到另外一个显存中,与前buffer做叠加。

 

应该说单buffer和双buffer各有擅长,关键在于如何灵活运用。

 

直写式(write through),也叫写透,即CPU在向Cache写入数据的同时,也把数据写入主存以保证Cache和主存中相应单元数据的一致性,其特点是简单可靠,但由于CPU每次更新时都要对主存写入,速度必然受影响。

回写式(write back),即CPU只向Cache写入,并用标记加以注明,直到Cache中被写过的块要被进入的信息块取代时,才一次性写入主存。这种方式考虑到写入的往往是中间结果,每次写入主存速度慢而且不必要。其特点是速度快,避免了不必要的冗余写操作,但结构上较复杂。

直写式和回写式有着截然不同的操作,在不同的场合,不同的内存块使用不同的回写策略(如果你的系统可以实现的话)要比使用一种策略要高效得多。具体一点,对于反复存取的内存块置成写回,而把一次写入而很长时间以后再使用的内存置为写透,可以大大提高Cache的效率。

第一点很容易理解,第二点就需要琢磨一下了,由于写透的操作是,当缓存有该地址的数据时同时更新缓存和主存,当缓存没有该地址数据直接写主存,忽略缓存。当该地址的数据很长时间后才被使用到,那么在使用的时候该数据肯定不在Cache中(被替换了),所以不如直接写入主存来得直接;

相反,如果使用写回操作,当 Cache中有该地址数据,需要更新该数据,设置dirty位,很长时间后再使用该数据或被替换的时候才将其刷进主存,这样白白的占据了宝贵的Cache;而当 Cache没有该地址数据时,情况更糟糕,首先需要将相应的主存数据(一个Cache line)导入Cache,再更新数据,设置dirty位,再等待被刷回内存,这种情况不仅占用了Cache的空间,还多一次从主存中导入数据的过程,同样占据总线,开销很大。至于为什么要先从主存中导入数据,是因为Cache往主存回写数据时是按照一个Cache line 单位来写的,但被更新的数据可能没有一个Cache line这么多,所以为了保证数据一致性,必须先把数据导入Cache,更新后再刷回来。

对于很多视频解码来说,帧写入过程是一个一次性的动作,只有在下一次作为参考帧时才会被使用到,所以帧缓冲内存可以设置为写透操作,而下一次使用它的时候很可能是作为参考帧来使用,而作为参考帧不需要反复的存取,只需一次读操作就可以了,所以效率并不会因为不经过Cache而降低。实验证明该方法可以使 mpeg4 sp解码提高20-30%的效率。

阅读(3211) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-05-05 10:48:56

好服月租型IT服务台登录中国,诚邀阁下莅临体验! 月租型ITSM软件,注册即可使用! 详情请登录官方网站:http://www.servicezon.com