一、客户端的缓存与缓存替换机制

客户端的资源缓存:

在客户端游戏中,通常有大量的资源要处理,这些可能包括贴图、动作、模型、特效等等,这些资源往往存在着磁盘文件->内存(->显存)的数据通路,因为从磁盘文件读入内存是一个昂贵的的操作,所以很多客户端中的处理方法是放入一个缓存,当读入一个文件到内存后,就在内存中为他暂时保留一段时间,下次在读入这个文件就不用重复从磁盘读了,这种优化带来了客户端效率的极大提升,比如在一个有上百玩家的场景,可能我们用的玩家模型资源都是一个,只是贴图不同而已,如果使用缓存,那么你只需要从磁盘读取一次玩家模型的文件,而如果不使用,你可能要反复读取上百次,IO操作的低效会让用户很卡。

缓存替换:

然而我们用户的内存是有限大的,如果我们把每个资源都读进去保留而不释放,游戏就会越来越吃内存,一个典型的大象网游的资源可能几个G,最坏的情况用户读入了所有资源到缓存而不释放,那么也会因为内存不够用而崩溃。所以这里就通常要选择一些缓存替换机制:即动态的释放和加入资源到缓存,有进有出,但是要保证尽量让用户IO操作减少,一种最乐观的情况是,存在缓存中的资源恰好是用户使用的最多的资源,使用较少的会被使用多的交换出去。这模仿了CPU的cache机制。

二、现有的一些缓存替换机制:

基于CPU和操作系统的一些经典的cache replacement算法,客户端的资源缓存替换机制有以下一些做法:

1.懒人型,最简单的。就是没什么交换算法,只管读入缓存,然后只是定期的或发现缓存太大时一次性的清空缓存重来,这种在清空后会经历一段加载资源的顿卡,突然发现目前我们游戏的机制就是这样的,尴尬。。。但是这可能符合简单粗暴实用的原则。

2.LRU算发:大名鼎鼎的算法,当出现替换时,总是替换那个 上次使用时间距离限制最远的那个,这种算法认为最近使用的就是最长使用的,这种算法被多数体系结构使用,不过在某些极端情况下会导致thrash(内存的剧烈颠簸),比如说当一段时间内需要加载的东西过多时,而加载的资源呈有序重复序列时可能缓存会被一遍遍的清空。

3.MRU算法:它与LRU对应,但是它总是交换出最近使用的那个,这个倾向于保存最老的那个,听起来很奇怪,但是它往往不单独使用,通常配合LRU使用,当LRU出现thrash时转到MRU算法会有所帮助

三、基于Age和Cost 的算法:

今天看到了一种算法基于Age和Cost,似乎对客户端的缓存替换研究的更加到位一些,这种算法梗概如下:

1.Age:

为每个缓存保存一个32位的Age值初始为00000000(也就是第一次载入缓存时)(文档暂以8位代替),,每当hit一次,当前的最低位置1,每个计数区间(或每一帧)这个Age左移一位,例如某个资源在几帧内Age的变化

frame1:00000001(used)

frame2:00000011(used)

frame3:00000111(used)

frame4:00011100(not used)

frame5:00111000(not used)

根据当前的age,可以算出Age percentage Cost APC=1的数量/总的位数

APC越高说明这个资源近段时间是越有用的,替换时选择APC低的替换

基于Age的算法更加精确的得出了最近一段时间内资源的使用率,找出比lru更合理的替换,

2.Age扩展算法:

上面的每一步是按照帧来算的,实际使用中没帧来统计肯定是有点过了,可以按照一定时间片来统计,在一定时间片内可能一个资源回被用到n次,因此扩展的Age算法就单纯的标记1改为标记n,即这个统计区间内被用到的次数,如上例

time1:00000005(used 5 times)

time2:0000005A(used 9 times)

time3:000005A1(used 1 times)

time4:0005A100(not used)

time5:005A1000(not used)

这样APC=各位的值相加/最大的可能值

例如某个模型资源在上一段时间内被100个玩家引用,那么替换他的代价就明显要高很多,Age的扩展方法考虑的引用的频次

3.Age&Cost:

在实际的操作中,有些资源的替换成本是非常大的,例如从硬盘读入一个10m的贴图显然比读入一个100k的贴图成本大很多,所以替换时不能相同对待,这里考虑的成本记为relative cost(RC),算法中将最终的缓存替换成本TC=APC*RC,这样来综合考虑,通常将APC取值区间规整为0-1,而将rc规整为 1-10(算法作者认为载入文件的时间成本权重更大)。这样对不同的资源为它赋值不同的载入时间成本RC,再乘以上面的Age算法中的APC(引用频率成本),综合得出了它的缓存替换成本。一种比较简单的rc的赋值可以用它的文件大小来自动赋值。

几个例子:

APC    RC    TC

1          10      10       这说明这个文件的替换成本非常大,主要是文件比较大,同时它引用的频率特别高,这种资源基本上不会轻易从缓存中替换出来

0.2       8         4        这个文件很大,但是引用频率还很低,所以替换程度是中等的

1           5         5        文件很小,说明载入很快,但是引用频率很高,所以可以替换出来(因为再载入的成本低),也可以不替换出来,中等的

0.1      10        1       这个文件很大,载入很慢,但是引用很少,也就是说内存中存在一个很占地方但是几乎不怎么用的资源,值得替换出来,节省空间,因为不常用再次载入就算费时也值得

比如我们的游戏中开场有一个非常大的贴图资源,用于登录界面,它最开始有60M,(游戏中一般的贴图在几百K以下),而它在游戏中不会再被用到,现有的算法这个很大的资源会一直占在缓存里,用户内存被无故吃了很多,但是应用本算法,它的RC在游戏中可以达到上限10,但是APC基本上是下限,也许0.01,所以他的TC可能只有0.1,将登陆之后很快的时间内被从内存中释放出来。

赶紧利用这个算法节省一下我们的内存

基于年纪和成本(Age & Cost)的缓存替换(cache replacement)机制的更多相关文章

  1. 搜索引擎的缓存(cache)机制

    什么是缓存? 在搜索领域中,所谓缓存,就是在高速内存硬件设备上为搜索引擎开辟一块存储区,来存储常见的用户查询及其结果,并采用一定的管理策略来维护缓存区内的数据.当搜索引擎再次接收到用户的查询请求时,首 ...

  2. HTTP请求的缓存(Cache)机制

    原文地址:http://small.aiweimeng.top/index.php/archives/58.html 先来一张图: ####下面简单的来描述一下HTTP Cache机制: 当资源资源第 ...

  3. 一个基于STSdb和fastJson的磁盘/内存缓存

    一个基于STSdb和fastJson的磁盘/内存缓存 需求 业务系统用的是数据库,数据量大,部分只读或相对稳定业务查询复杂,每次页面加载都要花耗不少时间(不讨论异步),觉得可以做一下高速缓存,譬如用n ...

  4. 缓存篇(Cache)~大话开篇

    回到占占推荐博客索引 闲话杂淡 想写这篇文章很久了,但总是感觉内功还不太够,总觉得,要写这种编程领域里的心法(内功)的文章,需要有足够的实践,需要对具体领域非常了解,才能写出来.如今,感觉自己有写这种 ...

  5. 从Java视角理解CPU缓存(CPU Cache)

    从Java视角理解系统结构连载, 关注我的微博(链接)了解最新动态众所周知, CPU是计算机的大脑, 它负责执行程序的指令; 内存负责存数据, 包括程序自身数据. 同样大家都知道, 内存比CPU慢很多 ...

  6. Kafka元数据缓存(metadata cache)

    经常有人问的一个问题就是:Kafka broker到底是不是无状态的?网上有这样的说法: 正常情况下consumer会在消费完一条消息后线性增加这个offset.当然,consumer也可将offse ...

  7. yii中缓存(cache)详解

    缓存是用于提升网站性能的一种即简单又有效的途径.通过存储相对静态的数据至缓存以备所需,我们可以省去生成这些数据的时间.在 Yii 中使用缓存主要包括配置和访问缓存组件 . 内部方法 一.缓存配置: 1 ...

  8. Cache replacement policies 缓存实现算法

    Cache replacement policies - Wikipedia https://en.wikipedia.org/wiki/Cache_replacement_policies Cach ...

  9. yii中缓存(cache)详解 - 彼岸あ年華ツ

    缓存是用于提升网站性能的一种即简单又有效的途径.通过存储相对静态的数据至缓存以备所需,我们可以省去生成 这些数据的时间.在 Yii 中使用缓存主要包括配置和访问缓存组件 . 内部方法 一.缓存配置: ...

随机推荐

  1. codevs 3693 数三角形

    /* n*m个点中选3个 再排除三点共线 共线分两类 1 在横线或者竖线上 m*C(n,3) n*C(m,3) 2 在对角线上 这个比较麻烦 以为对角线和矩阵是一一对应的 我们转化成求矩阵 并且保证有 ...

  2. Oracle 11g详细安装配置教程

    最近开始学习Oracle数据库了,根据我的理解Oracle数据库是一种强大.复杂.高性能的数据库,而且价格不菲,使用都是中大型企业,土豪专用.学习一种数据库的入门工作就是先安装这种数据库,鉴于大批道友 ...

  3. spring-data-mongodb一个系统xml文件里面配置两个数据源

    spring-data-mongodb一个系统xml文件里面配置两个数据源 参考文档如下: http://www.iteye.com/problems/92789 http://stackoverfl ...

  4. activiti_SpringEnvironment

    package main; import org.activiti.engine.ProcessEngine; import org.activiti.engine.ProcessEngines; i ...

  5. dropdownlist 二级联动

    protected void Page_Load(object sender, EventArgs e) { if (!Page.IsPostBack) { GradeBind(); } } //绑定 ...

  6. 日期 bootsrtap-datatimepicker and bootstrap-datepicker 控件支持中文

    引用 bootsrtap-datatimepicker and bootstrap-datepicker 控件,发现官方控件不支持中文 1,bootstrap-datepicker - >解决方 ...

  7. 经典shell面试题整理

    一.取出/etc/passwd文件中shell出现的次数 问题:下面是一个/etc/passwd文件的部分内容.题目要求取出shell并统计次数,shell是指后面的/bin/bash,/sbin/n ...

  8. MySQL中的binlog相关命令和恢复技巧

    操作命令: 复制代码 代码如下: show binlog events in 'mysql-bin.000016' limit 10; reset master 删除所有的二进制日志 flush lo ...

  9. 微信公众平台开发(一) ——实现URL接入

    一.填写服务器配置 登录微信公众平台,点击开发者中心,点击“修改配置”按钮,填写服务器地址(URL).Token和EncodingAESKey.URL是开发者用来接收微信消息和事件的接口URL.Tok ...

  10. MySQL是否在扫描额外的记录

    在确定查询只是返回需要的数据之后,接下来应该看看查询为了返回结果是否扫描了过多的数据.对于MySQL,最简单的衡量查询开销的三个指标如下: 1响应时间,2扫描行数,3返回行数 没有那个指明能够完美的衡 ...