TODO:分析程序的资源,代码逻辑,渲染逻辑
闪存优化
闪存用于存储游戏数据和资源,包括游戏数据、纹理、音频等。闪存的读写速度比内存慢得多,因此在游戏中,我们需要尽可能地减少闪存的读写次数,以提高游戏的性能。
闪存结构和文件操作流程
在性能优化-基础 中,介绍了相关的基础知识,为了文章的完整性,简单回顾一下。
- 闪存结构
- SOC系统中的闪存一般采用NAND Flash或NOR Flash,作为非易失性存储器,用于存储操作系统、应用程序、资源文件等。
- 闪存通过总线(如SPI、eMMC、UFS等)与SOC主控芯片连接。
- 文件读写流程
文件读取:
- CPU发起文件读取请求,操作系统通过文件系统(如FAT、EXT4等)定位文件在闪存中的物理地址。
- 文件系统驱动将读取命令通过总线发送到闪存控制器。
- 闪存控制器根据地址从闪存芯片中读取数据,经过总线传输到SOC的内存(RAM)中。
- CPU从内存中获取数据进行处理。
文件写入:
- CPU将需要写入的数据放入内存缓冲区。
- 操作系统通过文件系统分配闪存空间,并生成写入命令。
- 写入命令和数据通过总线传递给闪存控制器。
- 闪存控制器将数据写入指定的闪存地址。
- 写入完成后,文件系统更新元数据,保证数据一致性。
应用层API:
- fopen, fread, fwrite, fclose等函数封装了文件操作的底层细节,但最终都是调用到操作系统API。
- 也可以使用内存映射的方式,将文件映射到内存中,直接操作内存,避免了文件直接调用API读取的过程, 映射后可以直接操作指针的方式读取和写入内存。
序列化(Serialization)
序列化的概念
Unity 的序列化(Serialization)体系分为编辑器写盘阶段和运行时读盘阶段,它同时支持 二进制格式(Binary SerializedFile)和 文本(YAML)格式。编辑器在构建场景、AssetBundle 或玩家(Player)时,将所有 UnityEngine.Object 派生的对象及其字段按照 “Type Tree + 对象数据” 的方式写入磁盘;运行时则根据磁盘上的 Type Tree 快速定位并重构内存中的 C++ 对象,并通过隐藏指针 m_CachedPtr 将之挂载到对应的 C# 托管对象上。二进制格式在读写时采用专门的 C++ 引擎代码和内存拷贝技术,支持内存映射 (.resS/.resource) 与多线程解压,是极高效的;而文本(YAML)格式则使用文本解析器和反射,仅在编辑器中针对小规模场景或开启 “Force Text” 时使用
序列化数据结构
AssetBundle
AssetBundle 是一个各种资源序列化后的集合,包括脚本、纹理、模型、音频等资源。 #### AssetBundle文件结构