bookmark_border在android上用GPU做数字计算,效率比单线程java实现快了20~40倍?!

最近被一个android大量数据计算过程的提速问题困扰了一个星期,在尝试了各种办法之后,最终拜倒在了GPU的强大运算力面前。

 

我尝试过的实现一共有三种。

1. 平铺直叙的单线程java实现

这个主要是为了快速实现逻辑,用来检验代码正确性的,效率不是他需要考虑的问题,所以慢一点我也没什么意见。

 

2. jni调用C++,越过JVM,在native层实现运算逻辑

一开始实现完发现比java版快了10倍,顿时对native的效率赞叹不已。但之后总感觉哪里不对头,因为我记得java比C++只慢一点点,差距绝不会是一个数量级那么多。

后来检查发现是实现有误,纠正后整个运算竟然比java版还稍微慢了一点点。原因可能是java版里使用了android自己的jni版RGBtoHSV函数,而我无法从NDK平台直接调用android内置的实现,所以找了一个native版的实现,这个实现比java版慢了。

不管怎么说jni比java慢还是太反直觉了,可是用android-ndk-profiler测了一圈也没看出什么异常来,似乎纯粹的数字运算就是要耗费这么多时间。

这里需要强调的是,我的整个运算过程只调用了一次jni函数,慢不是因为频繁的跨语言通信导致的。

 

3. 借用GPU的力量进行运算。android平台强大的renderscript

实在不行就试试GPGPU这招我一开始就想到了,但是没想到实现起来会这么方便。这里真的要给android平台点个赞。

说来惭愧,游戏行业从业三年,我的3D编程能力还仅停留在对照教材实现示例的程度。本来这次都做好了3天入门OpenGL的打算了,没想到android自己内置了直接使用GPU的能力。启动运算传递数据的过程都可以直接从java中做到,我只需要额外学一个用来在GPU中执行的renderscript文件的写法就可以了。而这个renderscript语法类似C语言,比swift还好学啊。

renderscript最大的坑在于从出现到现在写法有变动。本来指导教程就少,里面还有很多已经变成了错误示范,无形坑人,最为致命。在跨过了这些教程坑以后路就平坦多了,业务逻辑的移植和结果验证一天搞定。

需要注意的是,renderscript本身并不保证一定会使用GPU,老版本的android好像只会用多线程CPU实现代替。不过我们项目的目标平台API LEVEL够高,不用太在意这个问题。

还有一点要说的是,renderscript目前只能做互不相干的大量运算,而像累加求和啊求最大值最小值之类各个运算结果之间会互相影响的密集计算要等android 7.0(API LEVEL24)以后才能支持,而且直觉上来说也不会有纯粹无关的运算那么快,不能过高估计他的效率。

 

以上,android版的优化总算是有惊无险的完成了。之后要研究iOS平台的同类问题,可能还会再写一篇总结。

其实我已经稍微调查了一下,遗憾的是iOS上似乎并没有android的renderscript这么方便的GPGPU支持,那到头来我还是要去入门一下OpenGL了,唉。(咦?我怎么还有点小高兴?!)

bookmark_border逆风?看我翻给你看!

 进了一家本土手游大厂,技术受到领导认可,被安排专门处理日常开发之外的一些微科研性质的工作,每月加班时间不到10小时。

在据说是页游史上销量之王的项目组担任一个除我之外公司内无人可以胜任的闲职,除了偶尔帮忙调查一些复杂bug以外,大部分时间工作不饱和。

10年前决心进入游戏行业时,我会想到未来自己竟会对现在这种处境感到满足吗?

在专业领域,我最讨厌的处境是“技不如人”。研究生时代在众神之间自卑到焦虑,工作后来到技术水准严重低下的环境中,竟成了佼佼者,开始自满了。

我现在这样进步全靠自学的状态,想必也是大多数人的工作处境——只能在舒适区活动。
那研究生时代被扔进大神堆里比较有助于成长吗?其实也不是,完全不是。现在回忆起来,那是一个完全的惊恐区,我和他人之间的差距大到我完全想象不到要经历怎样的训练才能和他们站在同一高度。留学时代,我增长的最多的是视野的高度,让一直活跃在井底的自己知道,之前给自己设置的最高目标其实是低的可笑。
让我技术增长最多的,是在学习区“活动”的日子。“活动”可以是写代码,可以是读协议,可以是使用工具。

再来比较我现在的处境。我每天都有在工作,所以工作量是有的,但我感觉不到自己有继续在高速成长,因为用的都是已经相对熟练了的技能。
为一个项目修修补补,锻炼的不是我写代码的能力,而是在庞大的项目代码中寻找关键逻辑的能力。在这一年多的时间里,我漫游项目代码,寻找关键逻辑的能力确实得到了锻炼,但渐渐的,我发现我能更快找到问题的症结不是因为我阅读陌生代码的能力增强了,而是因为我更加熟悉现在这个项目的代码了。
这就很悲哀了。毕竟现在的项目总有一天会结束,那么我习得的这些关于这个项目代码结构的知识也将变得毫无价值。注意,漫游项目代码并不让我获得设计类似架构的能力,至少是帮助十分有限。因为我每次都是在寻找框架中某个非常具体的底层逻辑,并不是在很高的抽象层次中统揽全局。

现在我基本可以确定日常的工作内容对我的专业技能提升速度接近为0了,那我要怎么应对呢?

首先,我在工作范围内,寻找新的工作内容。因为我的岗位的特殊性,基本上日常开发外的东西我都可以参与,所以我可以为美工和测试人员开发和改良他们的工具。这个工作有些我已经在做了,有些我已经预约下来了,这是我接下来一段时间最期待的工作内容了。

其次,我真的非常渴望在工作以外的环境中,尝试从0开始搭建整个游戏客户端服务器端包括之后长期运营更新的整套架构设计。
做得好不好,最好的测试时发布给玩家玩,这就需要整个项目有足够高的完成度,也就是说,这个项目需要是一个团队项目。
参与别人的项目也是可以的,不过要找一个技术水平适合我,至少是要在我之上的业余游戏团队,还是很难的。我在qq群贴吧论坛微博上到处寻找过,结果并不乐观。

自己做项目我最担心的是我没有项目管理能力,也就是项目很可能做到一半就坑了。
业余项目中我认识的最有PM能力的是《四叶妹妹》和《即使如此小镇依然转动》等漫画的翻译组织者“三角”。那种有他在项目一定能完成的安心感和从不会责怪讽刺组员,让组内始终保持和谐的领导力让我对他充满了好感。可惜我自己这里八字没一撇,之前在他那里翻译漫画交稿效率也不高,没有足够的说服力拉他来做游戏开发的PM,可惜。(然而我不会放弃的!)

没有PM能力,没有PM,怎么做?
我能想到的一个办法就是先做些小到不需要PM就能做完的小项目,积累对个人项目成功完成的信心,然后逐渐扩大下一个项目的规模。
这是此刻对我来说最具可行性的方案,但,我还有一个小问题,就是眼高手低,不屑于做小游戏(汗)。不过和上面那些做大项目没有PM力没有足够的热情支撑跨日持久的业余开发等问题相比,不屑于做小游戏这个小问题已经容易对付的多了。

就做小游戏吧,从模仿现有小游戏开始。

回想一下自己当年学做j2me小游戏时的劲头吧,一个个小游戏的项目名我可是从0001一路做到了0012呢,大概。
我会被9年前的自己比下去吗?哼,开玩笑。逆风?看我翻给你看!