为什么游戏引擎越来越像操作系统

很多开发者刚接触游戏引擎时。

会认为引擎只是一个更大的库。


例如:

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

这些技术看起来来自不同领域。


但背后都在解决同一个问题:

如何管理一个越来越庞大、越来越复杂的系统。


从这个角度看。

现代游戏引擎越来越像操作系统。

并不是因为开发者刻意模仿操作系统。


而是因为当软件规模增长到一定程度后。

许多问题最终都会收敛到同一种形态。


管理资源。

管理任务。

管理依赖。

管理复杂度。


而这恰恰也是操作系统诞生的原因。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐