游戏设计模式——面向数据编程(新)
目录
随着软件需求的日益复杂发展,远古时期面的向过程编程思想才渐渐萌生了面向对象编程思想。
当人们发现面向对象在应对高层软件的种种好处时,越来越沉醉于面向对象,热衷于研究如何更加优雅地抽象出对象。
然而现代开发中渐渐发现面向对象编程层层抽象造成臃肿,导致运行效率降低,而这是性能要求高的游戏编程领域不想看到的。
于是现代游戏编程中,面向数据编程的思想越来越被接受(例如Unity2018更新的ECS框架就是一种面向数据思想的框架)。
面向数据编程是什么?
先来一个简单的比较:
面向过程思想:考虑解决问题所需的各个步骤(函数)。
面向对象思想:考虑解决问题所需的各个模型(类)。
面向数据思想:着重考虑数据的存取及布局(数据)。
那么所谓的考虑数据存储/布局是什么意思呢?
这里引入2个有关CPU处理数据的概念:
-
单指令流多数据流(SIMD)
-
CPU缓存(CPU Cache)
单指令流多数据流(SIMD)
什么是SIMD
SIMD全称Single Instruction Multiple Data,单指令流多数据流,是一种采用一个控制器来控制多个处理器,同时对若干个数据分别执行相同的操作从而实现空间上的并行性的技术。
简单来说,SIMD技术可以让CPU在一个指令周期执行多个数据的操作(不过操作需要一样),而不是一个指令周期执行一个数据的操作。
为什么需要SIMD
在上面的介绍里,我们可以直观的知道最大的好处在于:可以允许CPU利用并行性快速处理多个数据。
但是局限性还是有的,SIMD技术一般对矢量算术型操作(例如矢量相加,矢量相乘)支持的很好,而不支持其他类型操作(例如分支判断和跳转)。
所以SIMD技术常用于CPU数据计算密集型应用,例如:
- 人工智能
- 物理计算
- 粒子系统
- 光线追踪
- 图像处理
支持SIMD技术的指令集
X86架构的CPU所支持SSE/SSE2/SSE3指令集就是典型的重点针对/支持SIMD功能的指令集。
目前的PC的CPU架构绝大多数都是Intel的X86架构,而ARM架构的CPU可以在很多消费性电子产品上看到,从可携式装置(PDA、移动电话、多媒体播放器、掌上型电子游戏,和计算机)到电脑外设(硬盘、桌上型路由器)甚至在导弹的弹载计算机等军用设施中都有它的存在。
(vs2019里项目设置可以找到指令集设置选项)
我们可以在IDE/编译器里设置好支持SIMD技术的指令集选项。
使用SIMD编程
使用汇编内联
缺陷:
- 汇编代码需根据不同平台定制(无跨平台特性)
- 汇编代码复杂,开发效率低
使用指令集库
缺陷:
- 代码需根据不同平台指令集,包含不同指令集库头文件(无跨平台特性)
使用ISPC语言
ISPC是英特尔推出的面向CPU的着色器语言,它适用多种指令集的矢量指令(如SSE2、SSE4、AVX、AVX2等)。
ISPC是基于C语言的,所以它大部分语法和C语言是一致的,可以减少学习成本。
ISPC源代码,经过编译后输出.obj文件和.h文件。这样我们在编写C/C++程序时可以包含该头文件以使用ISPC代码。
下面简单提供个代码示例比较:
// C/C++ Code id rgb2grey(