移动平台native代码遭遇的坑

最近客户端终于开始运行在移动平台上了(当然,快开发完才开始在移动平台尝试运行,本身就是一件很错误的顺序,然而这并不是我所能控制的),之前在PC平台上完全没问题的代码,开始出现一些诡异的问题。 为了保证客户端和服务器使用绝对相同的逻辑执行流程,我们采用C++来开发一部分native代码同时供客户端和服务端来使用。在迁移到移动平台时,这些native库在IOS和Android平台上出现了不同程度的水土不服。 首次在移动平台就发生了crash,并且只有Android平台会crash, 而IOS可以正常……

从CPU层面谈谈优化

大多数时间,大家都在从设计和算法上优化效率(这类优化往往效果比较明显,比如一个二分查找可以轻易将时间复杂度降低为lg(n))。但是在实现上,却很少有人注重实现效率,而理由是反正每年都会有更高频率的CPU出现,我何必花那个心思呢(Java程序员尤其擅长使用这个理由@_@)。 我个人不是完全同意上面的说辞,在不影响代码的可读性和花费不高的代价下,我习惯性的会写最我当前所知道的性能最高的写法。 在很早以前,我一度只有在编写汇编时才可以计算出汇编条数。随着代码量的增加,……

开卷有益(UNIX编程艺术篇)

最近《计算机程序设计艺术》看多了,每次写完代码之后,总会习惯估算一下指令级的开销。导致每次写代码都是性能导向,违反了很多设计准则。因此打算重新看一下《UNIX编程艺术》,来拉一下已经严重倾斜的天平。 刚看了二页,又想起一个困扰我多年的问题,而没想到的是这次我似乎想到了解决办法。 在写服务器程序时,将数据持久化到数据库,是一个必不可少的操作。它需要将一个结构体进行打包,然后通过网络发给数据库,数据库再进行,并将操作结果通过网网络返回给应用程序。虽然可以……

GC竞争问题

在阅读Lua GC源码中,我们就提到过一个细节,所有带有__gc函数的对象,在第一轮GC循环中只会执行__gc函数,直到第二轮GC才真正清除。 一直没有找到必须这样做的场景,直到最近我发生了一例GC竞争的bug之后,才恍然大悟。回过头想想,其实在我之前翻译Barry Hayes大神的一篇论文里也早都提到过,只不过当时例子是释放OS资源,而场景也太过抽象,才没有引起我的注意。下面来看一个MWE。 我已经尽可能的精简代码,然而还是需要170+LOC。 在这个例子里,实现了一个链表管理,所有的link……

通过Mesh投影来实现贴花系统

在做FPS之类的游戏中,如果枪打到了墙角,并不能简单放置一来弹孔面片了事。而是要像一张贴纸一样,完全与墙角贴合。这时就需要去实现一个贴花系统来达到这种效果。 贴花系统有几种不同的实现方式,但这里仅考虑通过Mesh投影来实现贴花系统的实现原理。 这种方式的本质是,找到视野中贴花资源会影响的Mesh, 并创建一个同样大小以贴花资源为纹理的Mesh覆盖上去,从而达到贴花的目的。主要分下面两步来实现。 1. 先找到会受影响的物体,比如将弹孔贴在两面墙的夹角,那么受影响的物体……

谈谈我对数据同步的理解

We性质b和网游最大的不同也许就在于数据同步。 Web的工作流程(这里不包括页游)虽然也有很多变化,但是一般都大致分为三步。 1. 在浏览器输入网址, 浏览器通过HTTP协议请求服务器加载数据,服务器在收到HTTP请求之后,从数据库加载相应的数据(有可能是HTML,JS等一些用于浏览器渲染的数据)并返回给客户端。这一步我称之为查询。 2. 浏览器收到服务器返回的数据之后,将数据渲染并呈现给用户。这一步我称之为渲染。 3. 用户在看到浏览器呈现的内容之后,根据需要去执行不同的操作……

又一个类型提升引起的Bug

在好几年前我已经中招过一次了, 没想到最近一不留神又中招一次。不过这次的花样和上次又不太一样。 Bug的起因是,我需要一个函数,根据指定速度(可能不是整数)和距离来获取到达目的点的时间,于是就有了下面这样一段代码。 //#define TIME time(NULL) #define TIME 1526796356 time_t foo(int distance, float speed) { return TIME + distance / speed; } int main() { printf("%ld\n", foo(30, 3.0f)); } 咋一看这代码几乎没毛病,严格……

Lua5.3 GC源码阅读(4)

接上篇, Lua中的GC采用的是三色垃圾增量回收算法. 因此真正进入singlestep函数之前, 先来简单介绍一下三色垃圾回收算法. 在三色垃圾回收算法有,每个可回收对象都会有”黑”,”白”,”灰”三种颜色. 所有对象刚创建都是白色(这里暂不考虑barrier的效果), 一个完整的GC循环大概如下: 1. GC从根对象开始遍历并为对象标记颜色.(这里需要明确的时,根对象并不是指前面的global_State.allgc, 而是指Lua中的一些全局对象,比如lua_State, 注册表) 2. GC每当发……

Lua5.3 GC源码阅读(3)

接上篇, 在真正阅读luaC_step源码之前,先来看一下Lua的垃圾回收器对外提供了哪些可调参数, 以及这些参数是如何控制垃圾回收器的. Lua提供了一个函数collectgarbage([opt[,arg]])用于控制GC的一些形为. collectgarbage通过第一个参数opt来执行不同的功能: “collect”: 执行一次完整的垃圾回收循环,这是默认选项. “stop”: 停止垃圾回收器的运行, 在调用”restart”前,回收器只有被显式调用时才运行. “restart”: 重新开始垃圾回收器的自……

Lua5.3 GC源码阅读(2)

上篇已经提到表作为lua中的一种对象,其生命周期是被GC管理的. 下面就从一个表的创建来分析GC模块是如何接管其生命周期的. 先来看一段lua代码 --a.lua local a = {} a.foo = "bar" 使用`luac -p -l a.lua` 得到如下结果 main <a.lua:0,0> (3 instructions at 0x20d7a50) 0+ params, 2 slots, 1 upvalue, 1 local, 2 constants, 0 functions 1 [1] NEWTABLE 0 0 0 2 [2] SETTABLE 0 -1 -2 ; "foo&……