PCEVA,PC绝对领域,探寻真正的电脑知识
打印 上一主题 下一主题
开启左侧

Mobile 3D Game Engine Solution-1

[复制链接]
跳转到指定楼层
1#
点击数:4640|回复数:7

本文只针对目前国内自研发手机游戏引擎做优化建议。虽然Vullkan支持Android,但是即使Vullkan在Android的生态圈完善了,仍然不可轻视某些优化。


Purpose

改善我们的引擎弊端,也是现阶段普遍移动端引擎的弊端:
过度的OO设计,AoS数据结构,导致大量CacheMiss CPU产生Stall

CPU并行化的合理利用

Ø场景更新并行化

Ø动画计算并行化

Ø可视裁剪并行化

Forward渲染架构:由于市面主流硬件的技术规格还在GLES2-GLES3层面,GLES2不支持MRT,采用Forward渲染架构较为容易实现

Ø场景复杂度相关的渲染计算

Ø光照计算开销昂贵O(n*m),不支持大量复杂的动态光源

ØPostProcess的带宽开销巨大

Ø纹理格式限制,只支持ETC1,不能使用RGBA格式的压缩贴图

Ø不支持GeometryInstancing

TBDR架构的兴起,对于大规模的复杂场景,反而增加带宽开销

UI系统

Ø不支持3D UI,没有3D UI的编辑方式

Ø不支持与粒子排序

粒子系统

Ø美术更习惯使用基于关键帧的编辑方式

Ø不支持与UI排序

Ø对于2D粒子的支持




Design

ØPipelineStall

ØOOD vs DOD

ØSSESIMDNEON

ØParallelScene Graph Management

Rendering

ØUnderstandingMobile GPU

ØGPUHardware Architecture

ØGPU Hardware Features Extensions

ØBuildDeferredShading On Mobile



Design

一些游戏引擎普遍的程序设计问题:
PipelineStall

ØConditionalBranch

ØCacheMiss

ØLHS

OOD vs DOD

ØAoS vs SoA

SSESIMDNEON

ParallelScene Graph Management



Pipeline Stall

CPUPipeline5层流水线)

ØIFInstructionFetch)读取指令

ØIDInstructionDecode)指令解码

ØEXExecute)执行指令

ØMEMMemoryAccess)内存访问

ØWBWriteBack)写回操作




PipelineStall4层流水线)

指令延迟,造成CPU停滞,导致原因:
Conditional Branch
Cache Miss
LHS
Etc.











Conditional Branch
ConditionalBranch(条件分支)
Ø导致不可预知的指令跳转,只有在执行阶段才能知道一条应该执行的指令,造成CPU延迟
Øif(x> 0) {a=0; b=1; c=2; } else d=3;



Ø现代CPU通过Branch Prediction来改善这种情况(仅仅是改善,取决于Prediction的准确度)移动端问题表现要严重N倍
Ø浮点分支造成的更严重Stall,因为浮点流水线更长


Conditional Move
ConditionalMove(条件转移)
Ø不打破程序流程结构,同时计算所有结果,根据条件进行跳转
Øfsel指令在不同硬件平台上分别使用fsel/fcmov/sse
fsel inPPC
fcmov inx87 FPU
ØConditionalBranch可能导致CacheMiss,造成Stall,使用ConditionalMove替代ConditionalBranch,可以获得更高的性能



Cache Miss
ØCPU读取数据(Fetch)优先访问CacheL1CacheL2Cache…),如果Cache中不存在该数据,即CacheMiss,则从主内存数据fetch数据到CacheCache将数据存储在若干个数据块内,称为Cacheline


Cache Miss



ClassDefinition To  Memory Layout





What’swrong with this code?




Why is it so slow?

Look at GetWorldBoundingSphere()







如何避免CacheMiss


场景更新,在每一帧应该只计算一次


LHS
LHS(Load-hit-stores)
Ø将数据写入一个地址,如果太快的尝试再次加载数据,就会出现CPU的停滞现象(Stall)
Ø造成这个问题的原因是,CPU计算时,Fetch主内存数据到寄存器(L1 Cache),处理完成时,将寄存器数据写回主内存。此时,如果在还没有写回完成时,访问该地址不能保证正确性,CPU要进行“同步”,产生Stall




Return*a+*b;执行该语句时,a和b地址还没有写回主内存,此时CPU不知道a地址是否等于b地址,是否需要写入到同一个地址,所以需要将a和b重新载入到寄存器,该过程发生“Stall

__restrict将a和b当做不同的地址对待,明确告诉CPU不需要写入到同一个地址,该过程不会发生“Stall”

Pipeline Stall


OOD VS DOD
OOD(ObjectOriented Design)
Ø使用AoS(Arrayof Structure)数据结构
Østd::vector<Node*>

由于内容术语比较小众,再加之一次性介绍篇幅较长,下一帖子中将继续声音内容,并且翻译成大众化语言。











本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
2#
SCE-PhyreEngine  楼主| 发表于 2016-4-24 00:29 | 只看该作者
后续内容,后天就发。如果大家希望用通俗语言解释,我就用袁腾飞说三国的模式讲出来。
3#
SCE-PhyreEngine  楼主| 发表于 2016-4-24 00:41 | 只看该作者
同时诚邀隔壁高手一起讨论
4#
笨啦灯 发表于 2016-4-24 00:54 | 只看该作者
大晚上的看到代码头好晕
5#
fastone 发表于 2016-4-24 13:56 | 只看该作者
你上次去做技术支持写的PPT?
6#
SCE-PhyreEngine  楼主| 发表于 2016-4-24 14:17 | 只看该作者
对。虽然他们是搞手机游戏的,但是还是去帮了一把
7#
111alan 发表于 2016-4-24 15:55 | 只看该作者
不做这方面表示有些函数名称没见过。。。大概就是这两种方法降低延迟?
1.处理“是”的同时也处理“否”
2.强制写到不同的缓存地址
8#
SCE-PhyreEngine  楼主| 发表于 2016-4-24 16:11 | 只看该作者
后续还有新内容,后续内容发出后,我将一些地方总结起来解释
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部