当前位置: 移动技术网 > 科技>办公>CPU > 存储设备IO优化向导

存储设备IO优化向导

2020年08月01日  | 移动技术网科技  | 我要评论
1、概述虽然存储设备的恨不能在近年来一直在稳步提升,从raw nand到emmc,再到UFS都在进步,但和CPU相比它们依然是一个低俗的外设,并且IO是不可抢占的,所以应用程序在交互中等待IO会带来非常糟糕的用户体验,大部分程序员都意识到了这一点,所以绝大多数的程序尽量都会想办法改善这个问题,例如预读(readahead)和异步IO等。但是有些场景是很难规避IO的影响的。比如启动应用和本地音视频播放。如果在这两个场景中,还有其它的程序来竞争IO,那对用户体验来说可能无法接受。2、现有的优化设想有

1、概述

虽然存储设备的恨不能在近年来一直在稳步提升,从raw nand到emmc,再到UFS都在进步,但和CPU相比它们依然是一个低俗的外设,并且IO是不可抢占的,所以应用程序在交互中等待IO会带来非常糟糕的用户体验,大部分程序员都意识到了这一点,所以绝大多数的程序尽量都会想办法改善这个问题,例如预读(readahead)和异步IO等。但是有些场景是很难规避IO的影响的。比如启动应用和本地音视频播放。如果在这两个场景中,还有其它的程序来竞争IO,那对用户体验来说可能无法接受。

2、现有的优化

设想有这样一个场景:某天用户心血来潮要整理设备上的照片或其它文件,通过文件浏览器把大量的文件拷到一张新的TF卡上,这个过程是很漫长的,这个时候他打开一个本地视频观看,但是不幸的事情来了,视频卡顿非常严重。

遇到这种情况,工程师们肯定能理解,文件拷贝和视频播放在竞争IO,导致解码器没有及时得到新的视频数据,进而导致丢帧或音视频不同步。但是用户不一定能接受这个解释。他觉得为什么不能把文件拷贝的速度放慢一些,优先保证视频播放的用户体验。

这时候又轮到工程师来想办法了,在这个场景中,IO实际上可以分两类,视频播放和文件拷贝。把其中视频播放的IO认为是关键IO,问题就变成 了如何避免关键IO拥塞。

让我们先看看万能的谷歌是怎么处理这个问题的,在最新的android版本上会设置所有视频相关进程的IO优先级到RT级,这种优先的效果肯定是有的,但是还有几个问题:

  • 效果有限 BT只能改善,而不能避免关键IO的拥塞,因为文件拷贝的进程会更频繁的发起IO请求,所以经常会碰到这种情况,视频播放的IO请求到来时,设备驱动正在执行文件拷贝操作的IO,由于IO不可抢占,此时只能等这个请求完成,视频播放的请求才能得到服务。
  • 对第三方应用支持有限 如果第三运用是通过MediaCodec或者OMX来实现音视频播放的,此时流媒体数据的请求是应用 自己发起的,并不会被自动配置成RT级
  • 没有考虑启动应用的场景 实测在文件拷贝的同时去启动应用,速度慢了近两倍

注:在线音视频缓存流媒体数据一般都是直接存在内在中的,一是可以保证性能,二是Flash设备的寿命有限,所以不需要考虑IO优化

3、如何改进

3.1、结合cgroup控制

kernel除了IO优先级以外,还有一个blk cgroup控制,目前支持两种控制策略:权重和节流。二者都是通过标准的cgroup方式提供配置接口的,这里就不详细描述了。把进程分组以后,可以给不同的分组配置不同的权重,例如给视频播放进程配置1000的权重,给文件拷贝分配10的权重,则内核会尽量按99:1的比例来分配存储设备的带宽,当然实际上的带宽比例不会是这样的,因为两个进程发起IO的频度是不一样的,内核只能保证短时间内的带宽按配置的权重来分配。而节流的话,则是可以给每个分组每个设备设置一个性能阈值,内核来保证性能不超过这个阈值,例如给文件拷贝分配2MB/s的读带宽,则内核会严格按这个指标分配带宽,即使此时设备带宽还没有用完。

3.2、提升第三方应用兼容性

大部分媒体应用都是直接调用MediaPlayer来实现播放,这样会通过MediaServer来读取流媒体数据,而这个进程android已经配置了RT优先级。但是还有一部分应用是直接调用MediaCodec来实现播放的,比如特殊的加密格式视频,又或者为了实现帧合成等特殊处理,在这种情况下是由视频应用本身来读取流媒体数据,为了改善这个问题,可以在dequeueInputBuffer函数中把当前线程IO优先级和权重都配置到最高。

3.3、识别启动应用的场景

所有的应用启动都要经过ActivityManagerService,所以AMS的startActivity中识别启动应用开始,在Activity.onStart中认为启动应用结束。

3.4、限制文件拷贝性能

为了进一步提升前台应用和媒体应用的用户体验,还需要降低文件拷贝的IO性能,即在识到到启动应用和音视频播放的场景后,会同时根据一个白名单(主要是各种文件浏览器),降低特定活动进程的IO优先级和权重,同时发出一个BROADCAST_IO_JANK的消息,各种系统服务如mtp服务、下载服务等可以在收到这个消息的时候降低IO优先级和权重。

3.5、提供框架层接口

框架层提供IO优先级和权重的配置接口,但是普通应用只支持降低优先级和权重,只有system权限的应用可以提高优先级和权重。

4、整体流程

  • step 1:开机启动过程中,init会为每个系统服务设定IO优先级和权重,其中media相关的进程全部都是RT和最高权重,debugerd、logcatd等都是IDLE和最低权重
  • step 2:AMS会在Activity的不同生命周期,设置不同的IO优先级和权重,其中TOP_APP > FORGROUND > BACKGROUD
  • step 3:媒体播放过程中会设置一个属性media.codec.running=true,来表示当前正在进行音视频编解码,并且会发出BROADCAST_IO_JANK消息,通知系统服务调低mtp、下载器和其它白名单中应用程序的IO优先级和权重到最低,并在播放结束后延迟发出BROADCAST_IO_RESUME(如果在延迟时间内触发新的BROADCAST_IO_JANK,会先移除这个延迟消息)通知系统服务恢复到正常优先级和权重。
  • step 4:在应用启动过程中,如果media.codec.running=false,则会发出BROADCAST_IO_JANK消息,通知系统服务调低mtp、下载器和其它白名单中应用程序的IO优先级和权重到最低,并在启动结束后延迟发出BROADCAST_IO_RESUME(如果在延迟时间内触发新的BROADCAST_IO_JANK,会先移除这个延迟消息),通知系统服务恢复到正常优先级和权重

 

本文地址:https://blog.csdn.net/xl19862005/article/details/108149101

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网