为什么游戏引擎越来越像操作系统
《游戏引擎为何越来越像操作系统》 随着游戏项目规模不断扩大,现代游戏引擎正在自发演化出类似操作系统的核心组件。当项目资源达到数万级别时,引擎开始需要资源管理器来处理加载/卸载、生命周期和热重载;多线程任务调度催生了类似进程调度器的Job System;内存管理系统发展出多种专用分配器;GPU资源管理借鉴了虚拟内存的分页思想;Render Graph则类似数据库查询优化器。这些演化并非刻意模仿操作系
为什么游戏引擎越来越像操作系统
很多开发者刚接触游戏引擎时。
会认为引擎只是一个更大的库。
例如:
Engine engine;
engine.createWindow();
engine.loadTexture();
engine.render();
看起来似乎只是把大量功能封装到一起。
但当真正深入现代引擎内部后。
你会发现一个有趣的现象。
随着规模增长。
游戏引擎正在不断演化出一些熟悉的东西:
内存管理器
任务调度器
资源系统
文件系统
句柄系统
虚拟资源
这些名字听起来并不像图形学。
反而更像操作系统。
这并不是巧合。
因为两者正在解决越来越相似的问题。
最初的程序不需要操作系统
早期软件十分简单。
程序启动:
读取数据
↓
执行逻辑
↓
退出
资源数量有限。
任务数量有限。
内存规模有限。
很多事情直接处理即可。
游戏引擎的发展也经历过类似阶段。
早期项目:
几十个模型
几十张纹理
少量场景
简单对象管理已经足够。
但规模增长之后。
情况开始改变。
第一件出现的东西:资源管理器
当项目拥有:
10000 张纹理
几千个模型
数百个场景
时。
问题开始出现。
例如:
new Texture(...);
谁负责销毁?
如何避免重复加载?
如何处理热重载?
如何统计引用?
于是出现:
Resource Manager
它开始统一管理:
Texture
Mesh
Shader
Material
看到这里。
已经有一点熟悉了。
因为操作系统也在做类似事情。
例如:
文件
进程
句柄
统一由系统管理。
而不是交给用户直接操作。
Handle 开始出现
上一篇文章讨论过。
现代引擎越来越喜欢:
TextureHandle
而不是:
Texture*
原因很简单。
系统需要控制资源生命周期。
于是:
Handle
↓
Manager
↓
Real Resource
成为常见结构。
这与操作系统中的:
File Handle
↓
Kernel Object
几乎如出一辙。
用户并不直接操作资源。
而是操作资源的引用。
Job System 开始像调度器
随着 CPU 核心不断增加。
现代引擎开始引入:
Job System
开发者提交:
工作
系统决定:
哪个线程执行
什么时候执行
此时:
Thread
已经退居幕后。
关注点变成:
Task
Dependency
Scheduling
这与操作系统中的:
Process Scheduler
高度相似。
本质上都在解决:
如何让有限计算资源高效运行。
内存管理越来越复杂
现代引擎很少直接依赖:
new
delete
更多时候会出现:
Arena Allocator
Pool Allocator
Linear Allocator
Frame Allocator
原因并不神秘。
当系统规模增长后。
内存本身变成一种资源。
需要:
分配
回收
统计
监控
而这正是操作系统内存管理器每天都在做的事情。
GPU 资源开始虚拟化
现代 GPU 已经拥有:
数 GB
几十 GB
显存。
但大型场景仍然可能超过这个规模。
于是开始出现:
Streaming
Virtual Texture
Virtual Geometry
开发者看到的是:
整个世界的数据
系统负责决定:
哪些数据驻留
哪些数据换出
是不是很熟悉?
因为这与操作系统中的:
Virtual Memory
拥有相同思想。
用户看到:
连续空间
系统负责:
分页管理
复杂度被隐藏到了底层。
Render Graph 开始像执行计划
传统渲染:
ShadowPass();
GBufferPass();
LightingPass();
执行顺序由程序员决定。
Render Graph 出现后:
Pass
Resource
Dependency
形成图结构。
开发者只描述:
需要什么
系统决定:
如何执行
这与数据库中的:
Query Planner
甚至操作系统中的:
Dependency Scheduler
拥有相似思想。
系统越来越倾向于:
声明目标
而不是:
手动安排步骤
为什么会发生这种演化
很多人认为:
引擎开发越来越复杂。
其实更准确地说。
是规模越来越大。
当系统拥有:
百万级实体
数万资源
数十核心
复杂依赖关系
时。
许多问题会自然出现。
例如:
资源如何管理?
任务如何调度?
内存如何分配?
数据如何加载?
这些问题与图形学无关。
它们属于:
系统工程
问题。
而操作系统恰好是人类处理这类问题最成熟的领域之一。
因此相似设计不断出现。
这并不意味着引擎真的变成了操作系统
当然。
游戏引擎并不会替代操作系统。
操作系统管理的是:
整个计算机
而游戏引擎管理的是:
整个游戏世界
两者目标不同。
但当规模足够大时。
它们会遇到越来越相似的问题。
于是产生越来越相似的解决方案。
结语
回顾现代引擎的发展过程:
资源越来越多。
于是出现:
Resource Manager
线程越来越多。
于是出现:
Job System
数据越来越大。
于是出现:
Streaming
Virtual Resource
依赖越来越复杂。
于是出现:
Render Graph
这些技术看起来来自不同领域。
但背后都在解决同一个问题:
如何管理一个越来越庞大、越来越复杂的系统。
从这个角度看。
现代游戏引擎越来越像操作系统。
并不是因为开发者刻意模仿操作系统。
而是因为当软件规模增长到一定程度后。
许多问题最终都会收敛到同一种形态。
管理资源。
管理任务。
管理依赖。
管理复杂度。
而这恰恰也是操作系统诞生的原因。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)