多核时代的移动开发(一)-函数式编程思想到来

在这里我们先初步分析一下目前移动游戏开发的概念与以往发生了怎样的改变。我们知道以前所谓的游戏开发与移动开发基本没有交集,移动游戏开发往往专指J2ME开发的一些小游戏,入门不难但是普遍用户体验不佳。而且由于J2ME标准不太统一所以造成移动游戏开发没有什么通用性,更难以形成统一的标准。但是由于平板及智能手机的普及,尤其是IPHONE的出现使移动游戏的核心领域迅速由2D向3D转换。

   一个新兴市场往往是最需要创意的,而随着市场的逐渐成熟则逐渐稳定与成熟的技术会变得越来越重要。我想对于移动的开发也是如此。那么目前移动开发最重要的,也是最本质的改观就是手机迅速由单核或者说是双核向着多核转变,目前比较流行的机型例如三星的NOTE2,S3等全部是4核,可以。可以预见很快就要完成到8核的进化

 

那么我们来分析一下结合移动平台目前的情况分析一下多核的趋势

1、  移动平台上的进程往往是用户当前进程通吃绝大部分资源的情况:与服务器或者桌面版系统不同,基本每个移动平台或者说是移动系统对于用户的当前进程的资源分配都有相当大的倾斜。所以往往是用户当前的使用进程可以占用全部CPU的资源,那么可以想象如果用户的程序拥有强大的CPU支持,但是只能完整的利用其中一核的效率,那么其实程序的效率也就无从谈起。

推论:移动平台上的多核性能优化不能指望操作系统,必须由应用开发设计人员来完成。

2、进程的多核优化不是简单的多起线程,有的朋友可能这样认为,多核的优化就是多起线程。其实这绝对是一种误区,绝大多数情况下还是主线程对于整个程序流畅性起到了绝对的作用,所谓的多程程往往是指用户进程向服务器或者操作系统请求数据的情况,其实用户进程绝对部分时间是在主进程上运行的。所以最需要优化的往往是我们的主线程,如果没有多线程运行就没法优化的说法是不正确的。

推论:如果要优化性能数据请求进程不是重点,而用户界面的主进程才是重头戏。

好让我们快速来举几个场景来分析一下情况,如果你是在做一个基于云端的手机应用,那么你的进程有一个很重要的任务是要解析XML报文,生成XML对象的数组,虽然编程框架如.NET或者J2EE等可以完成这样的工作,但是他的工作机制肯定是这样的,那么你需要遍历一下整个字符串,然后找到其中的标签和值,然后生成相应的对象。那么好问题来了,其实由于XML报文采用的是字典方式的数据组织形式,只要你知道标签的NAME就可以找到标签的值,而同一级别下的数据组织顺序没有关系,或者换种说法,那就是前一项的解析结果对于后一项的解析没有影响,那么没必要串行。OK透过简单的分析这种情况可以并行处理。

那么如果您做游戏那么其实情况就更多了,比如你在做矩阵变换,虽然不管XNA还是DX都会有相应的函数处理,其实还是遍历矩阵中的所有元素然后将此元素带入用某一方程式求值后放入新的位置。和上面的情况一样,每一项的处理结果均以单独立完成,互不影响,又没必要串行。

其实直白的解释并行的条件就是最终的计算结果的若干元素相互之间不产生影响,每一元素的生成均可以独立进行。那么总是回来了这种可以并行的情况JAVA或者C的类库有没有能你做优化?OK简单的看个例子,假如你有一个数组A[1,2,3,4]你需要把每个元素都加1形成这样的数据B[2,3,4,5],那么不管是C还是JAVA写法都类似。我以伪代码举例了

INT B[4];

FOR (INT I=0,I<A.LENGTH,I++)

{

B[I]=A[I]+1;

}

好结果代码是这么写的还有可能并行吗?

无论是哪个编译器都都必须让循环变量I执行I++的操作,才可以做B[I]=A[I]+1的动作。这个循环变量直接把一个可并行计算的机会葬送掉了。

其实这种循环变量的写法之所以没有被反强烈思过,是因为这种写法是贴近单核CPU的,他一步步的告诉CPU该怎么做。但是在多核时代这种表达方式不再适用。

再举个简单的例子:

比如银行的营业大厅以前常常是只有一个营业员那么假如你是营业经理设计流程就只能是一个人办理完成业务再进入下一个人(这样的方式类似于循环变量的方式)

但是目前银行的营业大厅里经常是四五营业员那么新的流程不能是一个人办理业务完成后再叫下一个人的方式不再适用。而是要让每个营业员都可以叫号。而之前规定只有一个客户办理完成业务的情况下才能让下一个客户进门办理业务的规则必须废止。

如果对于上面那个例子中所讲的对于A[1,2,3,4]中每个元素都加1的需求,函数式也就是并行式的语言是怎么做的呢?我以F#为例

Let add  x = x +1

List.map add [1 .. 4] 

这样就OK了。其实这咱写法也很好理解,先定义一个函数ADD就是把输入x加上1之后返回,而第二行的意思就是对于数据[1 .. 4]中的每个元素都执行add函数,并形成对应的元素。与FOR循环的做法相比,函数式语言避免了循环变量的出现带来的串行问题,虽然表达变简单了但是由于没有规定具体的实现,却增大了并行优化的空间。

好,这次的主要内容就是这些,总结一句话目前的多核移动时代,你可以不了解函数式语言的具体语法,但是不能不了解这种思想。后面的博客也不想就F#的具体语法来做详细介绍,但是我会尽我所能对函数式语言中所包含的思想进行介绍。

上一篇:MongoDB 分析查询性能


下一篇:STL中sort、priority_queue、map、set的自定义比较函数