您现在的位置:首页
--> 云风的 BLOG
几个月以前,在我在 blog 上曾谈及 Lua 5.2 的改进。它可以用来实现抢占式多线程 。 周末休息,我把这桩事挖出来娱乐一下,花了一整个晚上做了实现。把 lua 的每个线程锁定在独立的 lua state 中,强迫线程之间通过消息管道的方式通讯。经过测试,Lua 5.2 每个独立的 state 占用的内存很小。通过自定义 alloc 函数可以测算出,一个干净的 32bit state ,不含任何库函数时,占用内存量在 2K 以下(1726 bytes)。如果加载基本库,也仅仅占用不到 4K (3265 bytes)。若把所有 lua 官方标准库加载进来,才会上升到 10K 以上(12456 bytes)。 对于 luajit 2 ,这个基础开销会大一些,最小开销也在 10K 左右 (8058 bytes) 。加上 ffi 达到 30k (31605 bytes)。不过 ffi 可
MMORPG 中,场景信息同步是很基础而必不可少的服务。这部分很值得抽象出来,专门做成一个通用的服务程序。 此服务无非提供的是,向有需求的对象,同步场景中每个实体的状态信息。那么,我们分解需求,可以看到两点,一是提交状态,二是同步状态。 每条状态信息其实是由三部分构成,状态对象名(key)、状态值(value)、时间。 玩家、NPC、场景中的可变物品,其实都有可改变的状态。比如对象的位置坐标是最常见的状态。其它的状态还有玩家或 NPC 做的动作,玩家离线,上线,等等。可以有若干数据源向这个服务提供数据,如果借用 zeromq 中的模式的话,这个服务应该使用一个 PULL socket 收集数据。它获取从不同数据源 PUSH 来的,key-value 。然后打上时间戳,储存在内存中。 这个服务另外提供一个发布服务,向所有订阅者广播其收到的状态改变信息,每条信息包括推送来的 key-
• 游戏数值策划
这篇很淡疼的文章来源于我在微博上的争论。需要列数据,字数限制不合适,所以单列一篇了。 昨天翻出了元帅同学的一篇旧文,游戏数值设计(1):定义与目标 , 转发到微博上。我一向是喜欢看他吐槽的,这篇吐国内的 MMORPG 游戏策划分工的文章,深得我心。 我一直对国内 MMORPG 制作把设计人员分为 文案策划、系统策划、数值策划不以为然。文案拆分出去做倒还说得过去,这所谓系统策划和数值策划的拆分简直就是莫名其妙了。现代电子游戏从桌面游戏一路发展过来,怎样让玩家享受规则,一直是一个整体。如果一个人来设计一个游戏,那么脑子里必然要逐步形成这个游戏做出来是什么样子的,然后细化里面的细节,玩家在他设计的规则下怎么进行游戏。所谓数值设计,是这些细节里重要的一部分。 很难想像,一个设计人员来想游戏的玩法,然后说细节我不管了,有另一个人来负责就好了。然后再有一个人专心于填写 excel 表格,用加加减
我一直不太满意 google protocol buffers 的默认设计。为每个 message type 生成一大坨 C++ 代码让我很难受。而且官方没有提供 C 版本,第三方的 C 版本 也不让我满意。 这种设计很难让人做动态语言的 binding ,而大多数动态语言往往又没有强类型检查,采用生成代码的方式并没有特别的好处,反而有很大的性能损失(和通常做一个 bingding 库的方式比较)。比如官方的 Python 库,完全可以在运行时,根据协议,把那些函数生成出来,而不必用离线的工具生成代码。 去年的时候我曾经写过一个 lua 版本的库 。为了独立于官方版本,我甚至还用 lpeg 写了一个 .proto 文件的解析器。用了大约不到 100 行 lua 代码就可以解析出 .proto 文件内的协议内容。可以让 lua 库直接加载文本的协议描述文件。(这个东西这次帮了我大忙)
今天花了将近 3 个小时帮同事看一个崩在 lua VM 中的 bug 结果打乱了进度,没有在年前把预想的东西做完。其实说起来这不是个大问题,以前也碰到过。我检讨自己没有在看到出错时的调用栈时去看一眼 lua 相关的代码。如果是那样,因为以前遇到过同样的问题,所以就可以条件反射出问题原因,而不用荒废宝贵了数小时时间了。 唉,这下整合的进度没接上,过年不能自己一个人接着做下面的活了。 下面记录一下这个 bug ,提醒自己第三次...
• libuv 初窥
过年了,人都走光了,结果一个人活也干不了。所以我便想找点东西玩玩。 今天想试一下 libev 写点代码。原本在我那台 ubuntu 机器上一点问题都没有,可在 windows 机上用 mingw 编译出来的库一个 backend 都没有,基本不可用。然后网上就有同学推荐我试一下 libuv 。 libuv 是 node.js 作者做的一个封装库,在 unix 环境整合的 libev ,而在 windows 下用 IOCP 另实现了一套。看起来挺满足我的玩儿的需求的。所以就试了一下。这...
其实铁路订票系统面临的技术难点无非就是春运期间可能发生的海量并发业务请求。这个加上一个排队系统就可以轻易解决的。 本来我在 weibo 上闲扯两句,这么简单的方案,本以为大家一看就明白的。没想到还是许多人有疑问。好吧,写篇 blog 来解释一下。 简单说,我们设置几个网关服务器,用动态 DNS 的方式,把并发的订票请求分摊看。类比现实的话,就是把人分流到不同的购票大厅去。每个购票大厅都可以买到所有车次的票。OK ,这...
今天吃晚饭的时候想到,我需要一个定制的内存分配器。主要是为了解决 共享内存 中的字符串池的管理。 这个内存分配器需要是非入侵式的,即不在要分配的内存块中写 cookie 。 而我的需求中,需要被管理的内存块都是很规则的,成 2 的整数次幂的长度。buddy memory allocation 刚好适用。 算法很简单,就是每次把一个正内存块对半切分,一直切到需要的大小分配出去。回收的时候,如果跟它配对的块也是未被使用的,就合并成一个大...
前几天写的盒饭的问题 有很大争议。我并不认为我的结论一定正确,但我想讨论这个问题的人忽略了许多现实的复杂性。 我想说,这是个真实事件,并不是因为我想说明什么问题编的故事。我依然相信,我最后如果做一个交换,会更好一些。不过不想为这个事情争论下去 :) 我觉得这个问题和蒙特霍尔问题有相似之处,但并不相同。我也没想仔细去计算概率,直想快速判断,换或不换哪种得到正确结果的可能性更大。 下面我想向有兴趣讨论说说...
虽然 luajit 和 lua 5.2 还有点小矛盾,luajit 没有完全支持 lua 5.2 的迹象。不过,这些对 Lua 社区都是好消息啦。可能对于 lua 用户会有点小纠结,到底是追随官方的 5.2 版呢,还是去用性能更好的 luajit2 。我比较在意性能,暂时先投靠 luajit 了。反正和 5.2 区别也不大。更重要的是,luajit2 提供的 ffi 库相当之好用,极大的减少了我们写 C 库的 lua binding 的负担。从某种角度可以看到另一个问题,为基础设施模块设计出良好的 C 接口(而不是 C++ 的)是多么的重要。
• DNS 隧道
今天在 greader 上看到这么一篇,用 DNS 隧道实现免费上网。我的思绪猛然回到去年去新西兰度假的日子。 有那么几天,我们在惠灵顿的海边山顶租了个屋子,一切都很舒服,但是不能上网。甚至于附近连 wifi 信号都收不到,想"借用"一下别人的 wifi 热点都不成。我顶着海边的狂风在院子里竖起天线,捕捉着周围微弱的信号,最终未果。然后转战屋里的有线电视。我发现和国内的有线电视一样,机顶盒是接有网线的。也就是说,物理上,存在...
Google 正式发布 Google+ 的时候,我在山上。回到文明社会后,还好赶上了第一批用户的末班车,试用了一下。现在,重新开放,有更多的人尝试用 Google+ 。在数天之内,我就圈了接近 100 个朋友,被圈了近 1000 次。对于类似产品,我觉得算相当不错的成绩了。要知道,我 twitter 上只 fo 了不到 30 个人,douban 好友不到 50 个。基本上,不太熟的人,我都没有加的。而且这一切,还是在 google+ 迅速得到了 GFW 认证的前提下,取得的...
前几天分析了 lua gc 的实现细节。 阅读 lua 的代码是段很有趣的经历。但如果是重头读 lua 的源码,建议从简单的部分读起。gc 恰巧是最难的一段。LuaJIT 的作者 Mike 在这方面很有发言权,他在回答 Which OSS codebases out there are so well designed that you...
• 我在网易的十年
10 年前的今天,我在广州 36 楼办理了入职网易的手续。 这些年陆陆续续写了很多,原本计划在今天总结一下,突然又没有什么感觉了。入职第一天,肖海彤是我的引路人。他私下跟我说,我们没有那种灌输式的入职培训,我知道你也不喜欢那样。很多企业都喜欢那种洗脑式的培训,网易还没有。不过员工手册可以拿去读一下。 多年之后,我在杭州。阿里巴巴是我们的邻居。屡屡听到有入职阿里系的同学说起他们冗长的入职培训,我脑子里总会...
既然 MMORPG 都有千篇一律同质化的趋势,好歹我们技术人员也应该总结出点东西来,新项目开发可以用现成的模式。 一般来说,MMORPG 服务器要解决的问题无非是,同步玩家的位置,状态,把这些信息广播出去(细分的话,有非战斗环境和战斗环境);需要建立一个聊天服务,供玩家文字交流;有一个信息发布渠道;有任务 NPC 和玩家一对一交流;玩家调整自己的装备(也可以看成是和一特定 NPC 交流)。 以上,我们可以看到几个基本需求是可...
Bitcoin 为什么保值,BTC (Bitcoin 的货币简称)存在于一个庞大的 p2p 网络中。使用 Bitcoin 的群体公认了一种算法,这种算法在现今的条件下,每小时只会新产生大约 6 组新的 BTC ,目前一组是 50 个。也就是说,这个世界上,每个小时大约只会产生 300 个 BTC 。这个产量还会由网络自动调整难度来限制产量。你没办法通过修改所有人的 Client 的算法及参数(client 是开源的)来加快货币产量。伪造的货币会被网络丢弃(除非你可以控制大部分网络节点)。
本文的标题只是一个猜想,并不是我坚信的观点。事实上,我这几年自觉学到的重要东西之一,就是如何在开发过程中分工,如何信任队友开发的组件,如何组织许多人做同一个项目。 可是,如果这是一个骗局呢?那也未尝不是一种可能。 这个世界上我们需要做的软件可能没有太多真正庞大到需要很多人合作才做的出来。需要配置产品经理,需要设计人员,需要前端开发,后端开发等等。 更多时候,你需要很多人一起来完成仅仅是因为别人都这...
GC 中最繁杂的 mark 部分已经谈完了。剩下的东西很简单。今天一次可以写完。 sweep 分两个步骤,一个是清理字符串,另一个是清理其它对象。
今天来说说 write barrier 。 在 GC 的扫描过程中,由于分步执行,难免会出现少描了一半时,那些已经被置黑的对象又被修改,需要重新标记的情况。这就需要在改写对象时,建立 write barrier 。在扫描过程中触发 write barrier 的操作影响的对象被正确染色,或是把需要再染色的对象记录下来,留到 mark 的最后阶段 atomic 完成。
今天来看一下 mark 过程是怎样实现的。 所有的 GC 流程,都从 singlestep 函数开始。singlestep 就是一个最简单的状态机。GC 状态简单的从一个状态切换到下一个状态,循环不止。状态标识放在 global state 的 gcstate 域中。这一点前面以前谈过。 开始的两个状态和 mark 过程有关。 初始的 GCSpause 状态下,执行 markroot 函数。我们来看一下 markroot 的代码。
近3天十大热文
- [68] Go Reflect 性能
- [68] 如何拿下简短的域名
- [67] Oracle MTS模式下 进程地址与会话信
- [62] IOS安全–浅谈关于IOS加固的几种方法
- [61] 图书馆的世界纪录
- [60] 【社会化设计】自我(self)部分――欢迎区
- [58] android 开发入门
- [56] 视觉调整-设计师 vs. 逻辑
- [49] 给自己的字体课(一)——英文字体基础
- [48] 读书笔记-壹百度:百度十年千倍的29条法则
赞助商广告