游戏引擎学习第14天

视频参考:https://www.bilibili.com/video/BV1iNUeYEEj4/

1. 为什么关注内存管理?

  • 内存分配是潜在的失败点

    • 每次进行内存分配(mallocnew等)时,都可能失败(例如内存不足)。
    • 这种失败会引入不稳定性或不可预测性,需要额外的错误处理逻辑。
  • 传统编程的理念

    • 在“老派编程”中,作者更倾向于避免动态内存分配,通过静态或固定大小的缓冲区管理内存,从而使程序更加稳定和可靠。

2. 如何避免动态内存分配?

  • 示例中使用的策略
    • 程序需要两个缓冲区(一个音频缓冲区和一个位图缓冲区),它们通过操作系统一次性分配完成,且在整个程序生命周期内从不释放(never freed)。
    • 这种设计消除了动态内存分配的风险,也避免了与内存回收(如垃圾回收)相关的复杂性。

3. 动态内存分配的挑战

  • 现代编程环境的现状

    • 现代程序大量依赖动态内存分配和垃圾回收(如Java、C#中的GC机制)。
    • 动态内存管理可能导致性能抖动(如虚拟内存分页),难以预测程序的行为。
  • 作者的观点

    • 过多依赖动态内存分配,使得程序开发变得复杂且不可控。
    • 作者更喜欢“静态内存分配”或“固定缓冲区”的方法,使程序从一开始就处于稳定状态。

4. 静态内存管理的优点

  • 高可靠性

    • 程序一旦启动,就不会因为内存问题而失败。
  • 简单性

    • 减少内存泄漏和回收相关的复杂性。
  • 性能一致性

    • 消除了垃圾回收或虚拟内存分页带来的性能抖动。

5. 哲学层面的思考

  • 作者更喜欢探索传统编程中的一些“简单且有趣”的做法,比如尽可能避免动态内存分配。
  • 他认为,这种方法可以让编程回归本质——精心设计和实现代码,而不是依赖现代编程环境中的各种工具和机制。

这段视频主要在讨论内存分配的优化以及游戏开发中不同的设计思路。以下是对这段对话的简要总结:

  1. 内存分配策略

    • 演讲者建议采用预分配内存的方式,而不是在运行时频繁分配。
    • 他提到这种方法类似“旧学校”的平分区策略,即一开始抓取一块大内存,并为每个子系统预先分配固定的空间。
  2. 静态变量的使用

    • 演讲者提到使用 static 定义的“局部持久变量”,它本质上是一种作用域限制在函数内的全局变量。
    • 他不喜欢这种设计,因为它可能导致代码混乱和难以维护。
  3. 传统与现代的差异

    • 他对比了旧式街机程序员的开发风格和现代普遍的“内存分配狂欢”方法。
    • 强调大多数现代游戏不会采用他的方式,但他认为提供不同的视角是有意义的。
  4. 未来设计计划

    • 他计划展示如何将游戏状态存储在预先分配的内存中。
    • 演讲者希望避免动态分配,并使用更高效的方式管理内存。
  5. 强调多样化的视角

    • 演讲者明确指出,他并不是在提倡大家完全采用他的方式,而是提供一种不同的思考方式。

这种方法对某些嵌入式系统或资源受限的环境可能很有帮助,但在资源丰富的现代系统中可能并不常见。您对这段内容是否还有特定部分需要进一步解析?

在某些编程或系统设计情况下,处理失败案例的挑战,特别是与内存分配相关的挑战。

  1. 失败案例的策略

    • 必须有一个处理失败案例的计划。例如,每当进行新的资源分配时,需要检查分配是否成功,并妥善处理可能的失败情况。这可能需要复杂的逻辑来处理多种路径的成功或失败。
  2. 现实中的折中策略

    • 一种方法是通过测试运行系统,观察其内存使用情况,并确保启动时分配足够的内存。
    • 使用自定义分配器,预先分配一定的内存以避免运行中内存不足,但这种方法依赖于测试的全面性。
  3. 未知风险的接受

    • 有时,只能假设程序不会超出所需的内存范围,希望玩家或用户不会触发未考虑到的极端场景。这种方法依赖于假设和希望,而不是完全可靠的保障。
  4. 故事的必要性

    • 在设计系统时,需要为失败场景找到一个“故事”或策略,即使有时故事仅仅是“不清楚,但在测试中未发现问题”。
  5. 个人观点

    • 作者对这些策略并不满意,认为这些都不是理想的答案,但在实践中可能不得不接受其中之一。

平台抽象设计中关于游戏与平台之间交互的复杂性,以及如何简化这种交互。以下是总结:

  1. 循环调用的缺点

    • 游戏和平台之间频繁的双向调用(循环调用)会增加复杂性,使得理解两者之间的关联变得更加困难。
    • 这种复杂性在高级功能(如记录和回放整个游戏会话以进行调试)中尤为明显。
  2. 推荐的设计方式

    • 建议设计为简单的数据流模式:
      • 平台作为服务请求游戏提供必要的数据(如视频帧、音频输出等)。
      • 输入(如用户操作)直接传递到游戏,输出直接返回到平台。
    • 避免游戏层再调用平台,这种方式可以减少系统的耦合性,简化回放系统的实现。
  3. 单线程时代的优势

    • 在过去的单线程环境中,这种输入流和输出流定义明确的设计简化了调试工作(例如回放游戏的整个会话)。
    • 单一输入和输出流的模型使得系统在逻辑上更容易追踪和复现问题。
  4. 多核时代的挑战

    • 如今由于多核架构的普及,线程化操作增加了复杂性,使回放系统变得困难。
    • 线程化问题导致这种设计在现代环境中不再像过去那样具有优势。
  5. 结论

    • 过去单线程的设计逻辑有其历史意义和现实效率,但在现代多线程环境中,需要权衡线程管理的难度和系统简单性之间的关系。

游戏开发中的内存管理哲学进行了讨论。以下是要点总结:

  1. 内存管理的责任分配

    • 平台层在游戏启动时分配一块大内存给游戏。
    • 游戏负责对这块内存进行进一步分区和管理。
    • 游戏内的所有系统都必须在一个固定的内存空间中操作,确保游戏启动后能够运行至结束而不会因内存问题失败。
  2. 可靠性目标

    • 游戏开发的目标是做到“一旦启动,就不会失败”。
    • 即使某些资源(如精灵)丢失,游戏仍然能够正常运行。
    • 平台层可能会由于操作系统的问题而失败(例如 Windows 的设计缺陷),但这不会影响游戏的整体可靠性。
  3. 资源管理的哲学

    • 开发中采用“零失败状态”原则,即尽量减少游戏运行中的错误。
    • 提议了“金银铜”标准,以根据不同游戏的复杂程度评估其达到可靠性目标的水平。
  4. 延伸到磁盘 I/O

    • 与内存管理类似,对磁盘 I/O 的管理也遵循相同的哲学,以尽量减少失败。

作者表示,动态分配本质上是一种"自欺欺人"的做法,因为它假设内存是无限的,而实际上硬件的内存是有限的。如果不控制内存使用,程序可能会在运行时遇到不可预见的问题,如内存不足或碎片化。
采用主存池的方案,可以保证程序在固定内存下运行,减少风险。尤其是在面向最终用户的产品中,确保内存不会超出限制并且程序能顺利启动和运行是非常重要的。
1:03:31Why use the void* in game_memory?
在这段字幕中,主要的内容涉及内存管理和如何在游戏中处理不确定类型的内存块。可以从中提取出以下几个关键点:

  1. 不确定的内存块:由于游戏内存的某些部分是不确定的,我们不能为这些部分指定类型。这些部分被视为一个“大内存块”,游戏可以根据需要任意处理这些内存数据。

  2. void指针:提到使用空指针(或void指针)来指示这些不确定的内存块。因为我们不知道它们的具体类型,所以使用void指针来管理这些内存是一个常见的做法。

  3. 类型转换:虽然开始时内存块没有明确的类型,但可以在后续转换成具体的游戏状态或其他类型,并开始进行类型化管理。

  4. 游戏中的使用:游戏开发中常常需要处理各种类型的内存,这些内存数据可以根据需求灵活地操作和转换成具体的类型。

  5. “冷启动”和“冷转换”:提到的“冷启动”和“冷转换”暗示着这些内存块被快速转换成所需的格式,过程没有太多的复杂操作,直接转换为游戏所需要的状态。

  6. 游戏规模的影响:由于游戏的规模可能很大,这种内存处理方法显得尤为重要,能够动态地应对不同类型的内存需求。

存储管理和游戏开发中的一些技术概念。可以理解为以下几点:

  1. 永久存储和临时存储的区分

    • 永久存储:指的是游戏在运行过程中必须保持的数据,这些数据对游戏的持续运行至关重要,例如玩家的进度、已解锁的内容等。
    • 临时存储:是一些临时存储的数据,可以在不影响游戏运行的情况下清除或重新加载,例如缓存的纹理、声音等资源。
  2. 区分的原因

    • 性能优化:临时存储的数据可以被刷新(如在游戏运行时清空缓存),这有助于优化性能,减少内存占用。比如,在iPhone等设备上,清空缓存有助于减少应用的内存占用。
    • 事件驱动:临时存储的数据可能会受到某些事件的影响(例如用户的操作或系统事件),而这些数据不一定需要长期保存。
  3. 为什么分开处理

    • 这样做是为了能够对数据进行更灵活的管理,例如在需要时清除临时存储的数据,而不会影响到永久存储中的重要数据。
    • 这种区分还有助于一些额外的优化技巧,例如缓存和重新加载过程的优化。
  4. 后期调整

    • 在开发过程中,可能会根据实际需求调整永久和临时存储的具体实现,这种调整是灵活的,因此开发者可能会先写好代码框架,再根据实际情况做修改。

避免在平台层和游戏层之间进行频繁往返调用(即“往返旅行”),这种设计模式可能导致系统中的复杂性和性能问题。以下是一个简要的总结:

  1. 避免内存分配的往返:谈话的重点之一是避免频繁在平台层和游戏之间进行内存分配的往返。这种“往返旅行”指的是平台层调用游戏层,游戏层再调用回平台层,从而引入不必要的复杂性和性能开销。

  2. 虚拟化的例子:提到一个虚拟化的例子,试图通过设计避免频繁的内存分配和平台调用之间的交互,这样可以减少系统中的“蜘蛛网”式的复杂关系。

  3. 堆栈和调用关系:系统中创建了一个堆栈,其中平台层和游戏层交替调用,这种结构可能导致管理上的困难,尤其是当每个组件由不同的开发人员编写时。

  4. 简化设计:最后提到的优化建议是,如果设计得当(比如通过传递合适的参数),可以简化整个调用结构,使得系统运行更加高效且易于维护。

总的来说,这段对话强调了通过避免复杂的相互依赖关系和频繁的内存分配,可以让系统变得更高效、更简洁。

下面是平台独立内存代码的修改

在这里插入图片描述

任务管理器查看内存提交的大小

在这里插入图片描述

vscode 的一个小插件

在这里插入图片描述

    "workbench.colorCustomizations": {// 新增文本的背景颜色"diffEditor.insertedTextBackground": "#00501388", // 浅绿色,带透明度// 删除文本的背景颜色"diffEditor.removedTextBackground": "#62000088", // 浅红色,带透明度// 修改区域的边框颜色(可选)},

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/474120.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

游戏引擎学习第12天

视频参考:https://www.bilibili.com/video/BV1yom9YnEWY 这节没讲什么东西,主要是改了一下音频的代码 后面有介绍一些alloc 和malloc,VirtualAlloc 的东西 _alloca 函数(或 alloca)分配的是栈内存,它的特点是: 生命周…

django——创建 Django 项目和 APP

2.创建 Django 项目和 APP 命令: 创建Django项目 django-admin startproject name 创建子应用 python manager.py startapp name 2.1 创建工程 在使用Flask框架时,项目工程目录的组织与创建是需要我们自己手动创建完成的。 在django中,…

OceanBase 分区表详解

1、分区表的定义 在OceanBase数据库中,普通的表数据可以根据预设的规则被分割并存储到不同的数据区块中,同一区块的数据是在一个物理存储上。这样被分区块的表被称为分区表,而其中的每一个独立的数据区块则被称为一个分区。 如下图所示&…

学习大数据DAY61 宽表加工

目录 模型设计 加工宽表 任务调度: 大表 - 把很多数据整合起来 方便后续的明细查询和指标计算 模型设计 设计 建模 设计: excel 文档去编写 建模: 使用建模工具 PowerDesigner Navicat 在线画图工具... 把表结构给绘 制出来 共享\项目课工具\pd 加工宽表 数…

uniapp微信小程序转发跳转指定页面

onShareAppMessage 是微信小程序中的一个重要函数,用于自定义转发内容。当用户点击右上角的菜单按钮,并选择“转发”时,会触发这个函数。开发者可以在这个函数中返回一个对象,用于定义分享卡片的标题、图片、路径等信息。 使用场…

Datawhale组队学习】模型减肥秘籍:模型压缩技术3——模型量化

模型量化的目的是通过将浮点运算转换为定点运算,以减少模型大小、内存和存储需求,同时加快推理速度,降低计算功耗,使得模型在低算力设备上运行更加高效,特别适用于嵌入式设备或移动端场景。 不同数据类型(…

arkUI:网格布局(Grid)

arkUI:网格布局(Grid) 1 主要内容说明2 网格布局的相关内容2.1 基本使用2.1.1 源码1 (Grid网格布局)2.1.2 源码1运行效果 2.2 设置排列方式2.2.1 核心布局参数2.2.2 网格单元格参数(GridItem)2.…

Cherno OpenGL(28 ~ 33)

批量渲染-介绍 在这里我们将在一个drawcall打包多个几何体。即 batch geometry。 我们在这里将聚焦于2d渲染,我们如何渲染一堆2d的quads或者说rectangles呢? 一种情况是比如一个2d游戏有很多个tile组成,要去渲染这些tile;另一种…

网络安全之国际主流网络安全架构模型

目前,国际主流的网络安全架构模型主要有: ● 信息技术咨询公司Gartner的ASA(Adaptive Security Architecture自适应安全架构) ● 美国政府资助的非营利研究机构MITRE的ATT&CK(Adversarial Tactics Techniques &…

游戏引擎学习第16天

视频参考:https://www.bilibili.com/video/BV1mEUCY8EiC/ 这些字幕讨论了编译器警告的概念以及如何在编译过程中启用和处理警告。以下是字幕的内容摘要: 警告的定义:警告是编译器用来告诉你某些地方可能存在问题,尽管编译器不强制要求你修复…

【Nginx从入门到精通】03 、安装部署-让虚拟机可以联网

文章目录 总结一、配置联网【Minimal 精简版】1.1、查看网络配置1.2、配置ip地址 : 修改配置文件 <font colororange>ifcfg-ens33Stage 1&#xff1a;输入指令Stage 2&#xff1a;修改参数Stage 3&#xff1a;重启网络Stage 4&#xff1a;测试上网 二、配置联网【Everyth…

【UGUI】背包的交互01(道具信息跟随鼠标+道具信息面板显示)

详细程序逻辑过程 初始化物品栏&#xff1a; 在 Awake 方法中&#xff0c;通过标签找到提示框和信息面板。 循环生成10个背包格子&#xff0c;并为每个格子设置图标和名称。 为每个格子添加 UInterMaager232 脚本&#xff0c;以便处理交互事件。 关闭提示框和信息面板&#…

MySQL45讲 第二十四讲 MySQL是怎么保证主备一致的?——阅读总结

文章目录 MySQL45讲 第二十四讲 MySQL是怎么保证主备一致的&#xff1f;——阅读总结一、MySQL 主备基本原理&#xff08;一&#xff09;主备切换流程&#xff08;二&#xff09;主备数据同步流程 二、binlog 格式及相关问题&#xff08;一&#xff09;binlog 的三种格式&#…

RSA算法原理

1、RSA加密算法介绍 2、RSA算法的基本原理 2.1、RSA密钥生成 2.2、RSA加密和解密 1、RSA加密算法介绍 简单介绍一下&#xff0c;RSA算法是现代密码学的基石之一&#xff0c;广泛应用与安全通信、数据加密和身份验证等领域。 RSA加密是一种非对称加密算法&#xff0c;由罗…

html 图片转svg 并使用svg路径来裁剪html元素

1.png转svg 工具地址: Vectorizer – 免费图像矢量化 打开svg图片,复制其中的path中的d标签的路径 查看生成的svg路径是否正确 在线SVG路径预览工具 - UU在线工具 2.在html中使用svg路径 <svg xmlns"http://www.w3.org/2000/svg" width"318px" height…

哋它亢SEO技术分析:如何提升网站在搜索引擎中的可见性

文章目录 哋它亢SEO技术分析&#xff1a;如何提升网站在搜索引擎中的可见性网站的基本情况SEO优化分析与建议1. 元数据优化2. 关键词优化3. URL结构4. 图像优化5. 移动端优化6. 网站速度7. 结构化数据&#xff08;Schema Markup&#xff09;8. 内链与外链9. 社交分享 哋它亢SEO…

Liunx-Ubuntu22.04.1系统下配置Anaconda+pycharm+pytorch-gpu环境配置

这里写自定义目录标题 Liunx-Ubuntu22.04.1系统下配置Anacondapycharmpytorch-gpu环境配置一、Anaconda3配置1.Anaconda安装2.Anaconda更新3.Anaconda删除 二、pycharm配置1.pycharm安装 三、pytorch配置 Liunx-Ubuntu22.04.1系统下配置Anacondapycharmpytorch-gpu环境配置 一…

视觉SLAM--经典视觉SLAM框架

整个视觉SLAM流程主要包括以下步骤&#xff1a; 1、传感器信息读取&#xff1a;在视觉SLAM中主要为相机图像信息的读取和预处理。 2、前端视觉里程计&#xff1a;估算相邻图像间相机的运动&#xff0c;以及局部地图的样子。 3、后端&#xff08;非线性&#xff09;优化&#…

3、C语言基本数据类型关键字

本章学习目标&#xff1a; 1、认识存储单位&#xff1a;位bit和字节Byte 2、根据不同的应用场景选择符合需求的数据类型关键字,了解关键字的表示数据范围 1、内存单位 一、位 内存中的数据无论是文本、图像、音频还是视频&#xff0c;都是以位的形式进行存储的。 位是二进制…

Mac os 系统上如何开启远程登录的 ssh 22 端口

macOS 允许使用 SSH 连接&#xff0c;但为了安全起见&#xff0c;需要手动启动 SSH 服务&#xff0c;有两种方法可以激活远程登录。 方法一&#xff1a;界面化操作 1. 打开“系统偏好设置”&#xff0c;点击屏幕左上角的 Apple 图标&#xff0c;然后选择 系统偏好设置。 2. …